Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Сортировка по первой букве / цифре

#delphi #delphi_xe


Столкнулась с такой задачей. В текстовом файле имеются строки такого типа:

Беляев Антон Степанович 19.08.1986
Алексеев Денис Владимерович 20.06.1980
Еврошина Анна Петровна 30.07.1975
Belyaev Anton Stepanovich 08/19/1986
Alexeev Denis Vladimirovich 06.20.1980
Evroshina Anna Petrovna 07/30/1975
3.Belyaev Anton Stepanovich 08/19/1986
2.Alexeev Denis Vladimirovich 06.20.1980
1.Evroshina Anna Petrovna 07/30/1975


Вот вопрос: Как отсортировать список этих строк в алфавитном порядке.Что бы на выходе
получился результат (если есть номера в списке то сортировать просто по возрастанию).
То есть так:

1.Evroshina Anna Petrovna 07/30/1975
2.Alexeev Denis Vladimirovich 06.20.1980
3.Belyaev Anton Stepanovich 08/19/1986
Alexeev Denis Vladimirovich 06.20.1980
Belyaev Anton Stepanovich 08/19/1986
Evroshina Anna Petrovna 07/30/1975
Алексеев Денис Владимерович 20.06.1980
Беляев Антон Степанович 19.08.1986
Еврошина Анна Петровна 30.07.1975


Хотела бы добавить: Сложность в том что, в одном текстовом файле, фамилии как на
русском так и на английском + попадаются строки где идет нумерация фамилия имя отчество.
По этому я и не могу справится с этой задачей :(. Может есть какие функции или варианты
решение такой задачи или это не решаемая задача ?. Заранее благодарна за помощь...

Мои попытки сделать функцию сортировки по возрастанию:

var
 sl: TStringList;
 i: Integer;

function Compare(List: TStringList; Index1, Index2: Integer): Integer;
begin
 if List[Index1] > List[Index2] then
   Result := +1
 else if List[Index1] < List[Index2] then
   Result := 1
 else
   Result := 0;
end;

begin
 sl := TStringList.Create;
 sl.CustomSort(Compare);
 for i := 0 to sl.Count - 1 do
   WriteLn(sl[i]);
 sl.Free
end.

    


Ответы

Ответ 1



StrCmpLogicalW - функция сравнения строк, которая рассматривает цифры как числа, а не как строки. Пример использования: uses Winapi.ShLwApi, System.Generics.Defaults, System.Generics.Collections, System.SysUtils; var VItem: string; VItems: array [0..8] of string = ( 'Беляев Антон Степанович 19.08.1986', 'Алексеев Денис Владимерович 20.06.1980', 'Еврошина Анна Петровна 30.07.1975', 'Belyaev Anton Stepanovich 08/19/1986', 'Alexeev Denis Vladimirovich 06.20.1980', 'Evroshina Anna Petrovna 07/30/1975', '3.Belyaev Anton Stepanovich 08/19/1986', '2.Alexeev Denis Vladimirovich 06.20.1980', '1.Evroshina Anna Petrovna 07/30/1975' ); begin TArray.Sort(VItems, TDelegatedComparer.Construct( function(const Left, Right: string): Integer begin Result := StrCmpLogicalW(PChar(Left), PChar(Right)); end) ); for VItem in VItems do begin Writeln(VItem); end; Readln; end.

Ответ 2



Вот такой вариант решения проблемы. Что называется "в лоб". procedure TForm1.Button1Click(Sender: TObject); var List: TStringList; Begin List := TStringList.Create; try // Загружаем данные List.Add('Беляев Антон Степанович 19.08.1986'); List.Add('Алексеев Денис Владимерович 20.06.1980'); List.Add('Еврошина Анна Петровна 30.07.1975'); List.Add('Belyaev Anton Stepanovich 08/19/1986'); List.Add('Alexeev Denis Vladimirovich 06.20.1980'); List.Add('Evroshina Anna Petrovna 07/30/1975'); List.Add('3.Belyaev Anton Stepanovich 08/19/1986'); List.Add('2.Alexeev Denis Vladimirovich 06.20.1980'); List.Add('1.Evroshina Anna Petrovna 07/30/1975'); // Сортировка List.Sort; // Показываем результат for i:=0 to List.Count - 1 do ShowMessage(List.Strings[i]); finally List.Free; end; end; Уверен, что можно найти более элегантный способ решения, но если время дорого (а иначе не бывает), то я бы использовал такой подход.

Комментариев нет:

Отправить комментарий