Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.03.16;
Скачать: [xml.tar.bz2];

Вниз

Сортировка TStringList при OEM тексте   Найти похожие ветки 

 
Rakurs   (2008-02-16 12:09) [0]

Не подскажите как можно отсортировать строки в StringList"е если они не в Ansi, а в OEM (дос кодировке) ?


 
palva ©   (2008-02-16 12:56) [1]

А разве неправильно сортирует? Если у вас свои соображения о том, какая строка больше, а какая меньше, то напишите свою функцию для сравнения и передайте ее в качестве параметра метода CustomSort. Посмотрите в хэлпе.


 
Rakurs   (2008-02-16 13:19) [2]

да не правильно сортирует.
своих соображений нет :(
думал может есть какой флаг, указывающий что это OEM текст.

я не нашел в описании передачи параметров, только:
    procedure CustomSort(Compare: TStringListSortCompare); virtual;


 
Rakurs   (2008-02-16 13:21) [3]

или вы советуете переписать QuickSort ?


 
Rakurs   (2008-02-16 13:25) [4]

function TStrings.CompareStrings(const S1, S2: string): Integer;
begin
 Result := AnsiCompareText(S1, S2);
end;

а OEMCompareText  такой и нет или может как-то называется по-другому?


 
{RASkov} ©   (2008-02-16 13:31) [5]

> [2] Rakurs   (16.02.08 13:19)

Если:

> своих соображений нет :(

тогда:

> да не правильно сортирует.

- как узнал?


 
Rakurs   (2008-02-16 13:37) [6]

ну я смотрю что в итоге есть)
делаю tstring.sort, сохраняю отсортированный список в файл и смотрю...


 
Amoeba ©   (2008-02-16 20:08) [7]

В Windows встроенная OEM сортировка не предусмотрена, что естественно.


 
palva ©   (2008-02-16 20:20) [8]


> Rakurs   (16.02.08 13:19) [2]
> своих соображений нет :(

Как-то странно. Вы знаете что сортирует неправильно, но задать компьютеру правило для определения, какая строка больше, какая меньше не можете. Расшифруйте для компьютера, что такое OEM, и он сделает для вас, что вы просите.


 
Rakurs   (2008-02-16 21:43) [9]

Причем сдесь больше\меньше...
мне нужна сортировка по Алфавиту!
Ручками то можно написать свою процедурку, только не хочется лишний код, должно же быть что-то ....


 
Игорь Шевченко ©   (2008-02-16 21:57) [10]


> мне нужна сортировка по Алфавиту!


У кодировки OEM алфавит отличается от кодировки ANSI ?
Вот новость.


 
palva ©   (2008-02-16 22:07) [11]


> Причем сдесь больше\меньше...
> мне нужна сортировка по Алфавиту!

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

> Ручками то можно написать свою процедурку, только не хочется

Так процедурку писать не надо нужно написать функцию больше\меньше.

> лишний код, должно же быть что-то ....

Это что-то есть. См. [1]. Все нормальные пацаны этим пользуются.

Возможен такой вариант: перекодировать все строки, отсортировать, а потом перекодировать обратно. Правда это будет затратнее по ресурсам.


 
Anatoly Podgoretsky ©   (2008-02-16 22:27) [12]

> palva  (16.02.2008 22:07:11)  [11]

А не sign?
-1 0 1


 
palva ©   (2008-02-16 22:31) [13]

> У кодировки OEM алфавит отличается от кодировки ANSI ?
С буквами Ё ё есть разница. В OEM они стоят в конце, в ANSI - в начале.
Может быть, это имелось ввиду.


 
palva ©   (2008-02-16 22:50) [14]

Пример сортировки строк в обратном порядке:

{$APPTYPE CONSOLE}

uses Classes;

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.Append("asdf");
 sl.Append("zxcv");
 sl.Append("ghjk");
 sl.CustomSort(Compare);
 for i := 0 to sl.Count - 1 do
   WriteLn(sl[i]);
 sl.Free
end.


 
Rakurs   (2008-02-16 22:54) [15]

Спасибо, буду пробывать.
стандартно не только  в Ё проблемы, например мне так OEM текст отсортировался:
C..
Л..
5..
К..
М..
Я..


 
ЦУП ©   (2008-02-16 23:46) [16]

function D2W(const s: String): String;
begin
Result := s;
if Result<>"" then OemToChar(PChar(Result),PChar(Result));
end;

function W2D(const s: String): String;
begin
Result := s;
if Result<>"" then CharToOem(PChar(Result),PChar(Result));
end;

var
L: TStringList;
begin
L := TStringList.Create;
try
 L.LoadFromFile("c:\1.txt");
 L.Text := D2W(L.Text);
 L.Sort;
 L.Text := W2D(L.Text);
 L.SaveToFile("c:\2.txt");
finally
 L.Free;
end;
end;



> palva ©   (16.02.08 22:50) [14]


Вот проще процедура сравнения для обратной сортировки: -)

function CompareProc(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := -1;
if  List[Index1]>List[Index2]  then Exit;
Result := Integer(List[Index1]<List[Index2]);
end;


 
Leonid Troyanovsky ©   (2008-02-17 10:08) [17]


> Rakurs   (16.02.08 13:21) [3]

> или вы советуете переписать QuickSort ?

Мы советуем написать так:

type
  TOEMFileStream = class(TFileStream)
  public
   function Write(const Buffer; Count: Longint): Longint; override;
   function Read(var Buffer; Count: Longint): Longint; override;
 end;

function TOEMFileStream.Read;
begin
 Result := inherited Read(Buffer, Count);
 if Count > 0 then
   OEMToCharBuff(@Buffer, @Buffer, Count);
end;

function TOEMFileStream.Write;
begin
 if Count > 0 then
   CharToOEMBuff(@Buffer, @Buffer, Count);
 Result := inherited Write(Buffer, Count);
end;

--
Regards, LVT.


 
DiamondShark ©   (2008-02-17 11:23) [18]


> Leonid Troyanovsky ©   (17.02.08 10:08) [17]


> function TOEMFileStream.Write;
> begin
>  if Count > 0 then
>    CharToOEMBuff(@Buffer, @Buffer, Count);

Шоб тебе на том свете икнулось.


 
palva ©   (2008-02-17 11:57) [19]


> Вот проще процедура сравнения для обратной сортировки: -
> )

Я старался, чтобы мой код был понятен автору сабжа. Если говорить о простоте, то можно подключить, SysUtils, и процедура станет еще проще:

function Compare(List: TStringList; Index1, Index2: Integer): Integer;
begin
 Result := -StrComp(PChar(List[Index1]), PChar(List[Index2]))
end;

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

1. Самая затратная операция это сравнение строк. В процедуре их две. В нашем простейшем случае в нашем распоряжении оказалась стандартная процедура, которая делает тернарное сравнение. Если же такой процедуры нет, то было бы не плохо не пользоваться функциями сравнения строк, а написать собственное тернарное сравнение - это даже в том случае если процедура бинарного сравнения для вашего случая уже кем-то написана.

2. Если вы все же решили воспользоваться двумя вызовами бинарного сравнения, то имеет смысл подумать, в каком порядке проверять альтернативы. Если, скажем, алгоритм сортировки таков, что в большинстве случаев первый аргумент сравнения больше второго (последовательная вставка), то имеет смысл первым проверять именно этот случай. Конечно, вряд ли сортировка StringList использует этот примитивный алгоритм. В любом случае можно проверить это опытным путем. Можно поставить счетчики на каждую альтернативу и отсортировать большой массив случайных строк. Если счетчик на "больше" сильно отличается от счетчика на "меньше", то такая оптимизация имеет смысл.

3. Алгоритм сортировки может быть таким, что ему не нужна треться альтернатива. К примеру, он всегда проверяет на "меньше или равно" и не различает случаи "меньше" и "равно". Это также дает возможность обойтись одним бинарным сравнением. Хотя такая оптимизация в рабочих проектах категорически не рекомендуется, поскольку алгоритм может поменяться.

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

5. Можно добиться еще большего ускорения, если наследовать от StringList собственный класс, в котором переопределить функцию CompareStrings. Тогда можно будет пользоваться обычной функцие Sort, которую, кстати, тоже можно переопределить, если вам нужна не универсальность алгоритма а его эффективность именно для вашего случая. Собственная CompareStrings может сравнивать строки без образования временных строк и связанных с этим выделением и освобождением памяти и копированием символов.


 
Leonid Troyanovsky ©   (2008-02-17 12:00) [20]


> DiamondShark ©   (17.02.08 11:23) [18]

Дык, я, вроде, жив пока.

function TOEMFileStream.Read;
begin
 Result := inherited Read(Buffer, Count);
 OEMToCharBuff(@Buffer, @Buffer, Count);
end;

function TOEMFileStream.Write;
begin
 CharToOEMBuff(@Buffer, @Buffer, Count);
 Result := inherited Write(Buffer, Count);
end;

--
Regards, LVT.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.03.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.006 c
2-1203341458
igroman
2008-02-18 16:30
2008.03.16
Помогите с программкой


2-1203329126
WebSQLNeederr
2008-02-18 13:05
2008.03.16
Перемешать рендомно строки TStringList


3-1193207531
Aladdinych
2007-10-24 10:32
2008.03.16
Table busy


2-1203413997
KyRo
2008-02-19 12:39
2008.03.16
Компонент TGauge


11-1185293436
Dy1
2007-07-24 20:10
2008.03.16
колонки ListView





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский