Сортировка массивов по алфавиту? - PullRequest
3 голосов
/ 21 сентября 2011

Скажем, у меня есть два массива строк с именами 'arrayone' и 'arraytwo'. Как мне отсортировать 'arrayone' по алфавиту (от A до Z), сохраняя при этом отношения ко второму массиву.

В случае, если вам интересно, что находится в 'arrayone' и 'arraytwo', у 1 есть фамилии, а у 2 - возраст каждого человека.Мой конечный результат - добавить его в рихедит.

Пример сценария:

Smith           25 
Appleseed       32
Gibbs           45

Должен превратиться в:

Appleseed       32
Gibbs           45
Smith           25

Пожалуйста, без списка строк, сохраните его впростой массив и в процедуре.

ОБНОВЛЕНИЕ: я переключился на запись.

Попробовал этот код безрезультатно

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;

Там написано Несовместимые типы: 'Char' и'Строка'

Ответы [ 4 ]

17 голосов
/ 21 сентября 2011

Дав вам совет относительно структуры ваших данных и увидев последующую борьбу, я хочу разобраться и объяснить более четко, что я имею в виду.

В вашем исходном коде было два массива, которые по существу не были связаны между собой.Вы можете поменять элементы в одном массиве и легко забыть сделать это для другого массива.Мне кажется, что пары имя / возраст на самом деле не должны быть разделены.Это приводит к следующему объявлению типа.

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

Теперь вам нужно хранить массив TPerson.

type
  TPersonArray = array of TPerson;

Чтобы выполнить сортировку, вы должны иметь возможностьсравните два элемента и поменяйте их местами.

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;

Теперь мы можем собрать все это вместе с сортировкой по пузырькам.

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;

Теперь, если вы хотите использовать более сложный оператор сравнениятогда вы можете просто заменить Compare.Например, если вы хотите упорядочить по возрасту людей с одинаковыми именами, используйте функцию лексикографического сравнения.

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;

Я написал этот ответ по частям, и именно так вы должны подойтибольшая проблема, как это.Попробуйте разбить его на более мелкие кусочки, каждый из которых является управляемым.

3 голосов
/ 21 сентября 2011

Наша TDynArray оболочка просто обрабатывает эту функцию явно.

Вы можете отсортировать любой существующий динамический массив непосредственно на месте или использовать целочисленный массив индексов с пользовательской сортировкой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;

Кстати, в методе сортировки оболочки будет использоваться оптимизированная быстрая сортировка, которая намного быстрее алгоритма Bubble Sort.

В этом намного больше функцийобертка, например TList-подобные методы, такие как Add () или Delete (), использование внешней переменной Count (намного более быстрое добавление), сериализация или быстрый поиск с использованием хеширования.

Работает с Delphi 5 до XE2,и является открытым исходным кодом.

2 голосов
/ 21 сентября 2011

Не создавая новую структуру, которая содержит оба набора точек данных, вы можете отсортировать массив индексов с помощью функции сравнения, которая проверяет на основе массива.

Конкретнее, создайте массив indices с помощью indices[i] = i изначально.

Затем сортировка indices с использованием функции сравнения

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

Затем чтение arrayone[indices[0]], arrayone[indices[1]] ... дает вам отсортированный список, и соответствующие значения arraytwo[indices[0]], arraytwo[indices[1]], ...

1 голос
/ 21 сентября 2011

Сортируйте первый массив как обычно, используя алгоритм сортировки по вашему выбору. Любой вводный алгоритм учебника будет иметь несколько. Каждый раз, когда вы меняете две записи первого массива, вносите одно и то же изменение в соответствующие записи второго массива.

...