Sorting of Arrays Alphabetically?

限于喜欢 提交于 2020-01-02 08:43:31

问题


Say I have two arrays of string, named 'arrayone' and 'arraytwo' How would I go about sorting the 'arrayone' alphabetically (from A to Z), while still keeping relations to my second array.

Incase you were wondering what is in 'arrayone' and 'arraytwo', 1 has surnames and 2 has the ages of each person. My end result is to add it to a richedit.

Example of scenario:

Smith           25 
Appleseed       32
Gibbs           45

Must turn into:

Appleseed       32
Gibbs           45
Smith           25

Please no stringlist, keep it in simple array and in a procedure.

UPDATE: I switched to record.

Tried this code with no avail

for i := 0 to 26 do
for j := 0 to 26 do
  if recordname.surname[j] > recordname.surname[j+1] then begin
    line := recordname.surname[j];
    line[j] := recordname.surname[j+1];
    recordname.surname[j+1] := line;
  end;

It says Incompatible Types: 'Char' and 'String'


回答1:


Having given you advice about your data structure, and seen the ensuing struggles, I want to put things straight and explain more clearly what I mean.

You original code had two arrays that were essentially unconnected. You could swap items in one array and easily forget to do so for the other array. It looks to me like the name/age pairs really should not be split apart. This leads to the following type declaration.

type
  TPerson = record
    Name: string;
    Age: Integer;
  end;

Now you need to hold an array of TPerson.

type
  TPersonArray = array of TPerson;

In order to perform a sort you need to be able to compare two items, and swap them.

function Compare(const Person1, Person2: TPerson): Integer;
begin
  Result := CompareText(Person1.Name, Person2.Name);
end;

procedure Swap(var Person1, Person2: TPerson);
var
  temp: TPerson;
begin
  temp := Person1;
  Person1 := Person2;
  Person2 := temp;
end;

Now we can put this all together with a bubble sort.

procedure Sort(var People: TPersonArray);
var
  i, n: Integer;
  Swapped: Boolean;
begin
  n := Length(People);
  repeat
    Swapped := False;
    for i := 1 to n-1 do begin
      if Compare(People[i-1], People[i])>0 then begin
        Swap(People[i-1], People[i]);
        Swapped := True;
      end;
    end;
    dec(n);
  until not Swapped;
end;

Now, if you wanted to use a more complex comparison operator then you could simply replace Compare. For example, if you wanted to order by age any people that have the same name, then you use a lexicographic comparison function.

function Compare(const Person1, Person2: TPerson): Integer;
begin
  Result := CompareText(Person1.Name, Person2.Name);
  if Result=0 then begin
    Result := Person2.Age-Person1.Age;
  end;
end;

I have written this answer piece by piece and that is how you should approach a larger problem like this. Try to break it down in to smaller pieces, each of which is manageable.




回答2:


Our TDynArray wrapper just handle this feature explicitly.

You can sort any existing dynamic array directly in-place, or using an integer array of indices, with a custom sort function.

function PersonCompare(const Person1, Person2: TPerson): Integer;
begin // sample function pasted from David's answer
  Result := CompareText(Person1.Name, Person2.Name);
  if Result=0 then 
    Result := Person2.Age-Person1.Age;
end;

type
  TPersonDynArray = array of TPerson;

function SortPersons(var Persons: TPersonDynArray);
var
  Person: TDynArray;
begin
  Person.Init(TypeInfo(TPersonDynArray),Persons);
  Person.Compare := PersonCompare;
  Person.Sort;
end;

By the way, the Sort method of the wrapper will use an optimized Quick Sort, which is much faster than Bubble Sort algorithm.

There are much more features in this wrapper, e.g. TList-like methods like Add() or Delete(), use of an external Count variable (much faster adding), serialization or fast find using hashing.

It works from Delphi 5 up to XE2, and is Open Source.




回答3:


Without creating a new structure that contains both sets of data points, you can sort an array of indices with a comparison function that checks based on arrayone.

more concretely, create an array indices with indices[i] = i initially.

Then, sort indices using the comparison function

i < j iff arrayone[indices[i]] < arrayone[indices[j]]

Then, reading arrayone[indices[0]], arrayone[indices[1]] ... gives you the sorted list, and the corresponding values are arraytwo[indices[0]], arraytwo[indices[1]], ...




回答4:


Sort the first array as normal, using the sorting algorithm of your choice. Any introductory algorithm textbook will have several. Each time you swap two entries of the first array, make the same change to the corresponding entries of the second array.



来源:https://stackoverflow.com/questions/7492993/sorting-of-arrays-alphabetically

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!