Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.11.24;
Скачать: CL | DM;

Вниз

Про сортировочку   Найти похожие ветки 

 
Rouse_ ©   (2013-06-01 14:18) [0]

После вчерашнего мини ММР с украинскими коллегами, чей-то вдруг вдохновился и выдал :)
http://alexander-bagel.blogspot.ru/2013/06/windows.html


 
Eraser ©   (2013-06-01 14:22) [1]

http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx
оно? )


 
Rouse_ ©   (2013-06-01 14:24) [2]

Оно, только работает через одно место, собственно о чем и отписывается народ:


> Not always so logical
> If you have the names
>
> 0, 00, 000, 000_A, 000_B
>
> I expected it to be sorted
>
> 0
> 00
> 000
> 000_A
> 000_B
>
> But I get
>
> 000
> 000_A
> 000_B
> 00
> 0


 
Eraser ©   (2013-06-01 14:26) [3]

вот подлецы, наплодили функций в API, а сами ими не пользуются )


 
Rouse_ ©   (2013-06-01 14:27) [4]

ЗЫ: ну и на W2K, которую все еще саппортят, ес не ошибаюсь ее нет :)


 
Rouse_ ©   (2013-06-01 14:28) [5]

Надо кстати действительно дополнить статейку, а то будут еще пруфлинки давать :)
Пасип :)


 
брат Птибурдукова   (2013-06-01 14:31) [6]


> Rouse_ ©   (01.06.13 14:18) 
Ну если был в Киеве и не предупредил, объявлю вендетту…


 
Rouse_ ©   (2013-06-01 14:57) [7]


> Eraser ©   (01.06.13 14:26) [3]

Готово, кстати посмотри результат такой сортировки :)


> брат Птибурдукова   (01.06.13 14:31) [6]
>
> > Rouse_ ©   (01.06.13 14:18) 
> Ну если был в Киеве и не предупредил, объявлю вендетту…

Димч, ты чего? Я ж знаю что за такое мне сразу пожизненный эцих с гвоздями :)
Не, Пашка Голубь вчера приезжал просто :)
Народ собирали по сарафанному радио, решили глобальный сейшен не делать, ибо было чего на профтемы пообсуждать (за бабло трещали короче) :)


 
Розалия Самойловна   (2013-06-01 15:07) [8]


> Rouse_ ©   (01.06.13 14:18)
> После вчерашнего мини ММР с украинскими коллегами

Ты конечно этот пост сотрешь, и ветку закроешь...
Но, по-моему, ты так обрадовался встрече с украинскими коллегами, что сильно навстречался...

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

Получается, что ты разбиваешь строку на две сущности, одна из которых число - но для тех областей где это необходимо, эти сущности и так разделены и нормально сортируются при помощи ORDER BY f1 f2 с последующим, при необходимости, соединением строк при выводе.

Т.е. для общего случая сортировка Windows более правильная.


 
Rouse_ ©   (2013-06-01 15:11) [9]


> Ты конечно этот пост сотрешь, и ветку закроешь...

Почему?


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

Да это вообще можно сказать не сортировка, это просто воспроизведение аналогичной сортировки из проводника :)


> Получается, что ты разбиваешь строку на две сущности, одна
> из которых число - но для тех областей где это необходимо,
>  эти сущности и так разделены и нормально сортируются при
> помощи ORDER BY f1 f2 с последующим, при необходимости,
> соединением строк при выводе.

А вот это не понял, это ты про базы уже говоришь?


> Т.е. для общего случая сортировка Windows более правильная.

И этого тоже не понял, сортировка Windows это что?
Имеется ввиду lstrcmp?


 
Eraser ©   (2013-06-01 15:12) [10]


> Rouse_ ©   (01.06.13 14:57) [7]

да уж ) результат StrCmpLogicalW, мягко скажем, странный.

вообще за функцию спасибо, ей применение найдется, вот только опять этот Делфи 7 без юникода ))


 
Rouse_ ©   (2013-06-01 15:14) [11]

Работает и на Delphi7 и на Юникодных Delhi 2009 и выше (она сначала на них и писалась под задачу, это я уже потом причесал чтоб под семеркой собралась :)


 
Eraser ©   (2013-06-01 15:23) [12]

нашел ошибку в вызове StrCmpLogicalW.

вместо

 Result := StrCmpLogicalW(@S1, @S2);


нужно вот так
 Result := StrCmpLogicalW(PChar(S1), PChar(S2));


 
Eraser ©   (2013-06-01 15:25) [13]


> Eraser ©   (01.06.13 15:23) [12]

результат аналогичен твой функции на прошитом наборе данных. (win 8).


 
Rouse_ ©   (2013-06-01 15:26) [14]


> Eraser ©   (01.06.13 15:23) [12]
> нашел ошибку в вызове StrCmpLogicalW.

Вах, во я прошляпил...
Правлю...


 
Розалия Самойловна   (2013-06-01 15:28) [15]


> И этого тоже не понял, сортировка Windows это что?

Это default сортировка Проводника Windows.


> А вот это не понял, это ты про базы уже говоришь?

Не совсем так. Я говорю о том, что там где нужен твой тип сортировки уже давно применяются сортировка a-la сортировки БД.

Вот продемонстрирую на таком примере.
Ты считаешь что сортировка вида:

1a1
1a2
1a100

правильная.
Но правильная она будет только лишь в том случае, когда 1-2-100 это порядковые числа.
Но когда это другая сущность, например номер версии или ответвления, и запись вида 100 значит 1-0-0 (версия 1 подверсия 0-0) то будет правильной именно:

1a1
1a100
1a2

Т.е. не зная истинного значения сортируемой строки сортировать нету смыла.
А твой вид сортировки "как-бы-налету" придумывает слысл для строчки.


 
Rouse_ ©   (2013-06-01 15:34) [16]


> Это default сортировка Проводника Windows.

Так я ее и воспроизвожу.


> Но когда это другая сущность, например номер версии или
> ответвления, и запись вида 100 значит 1-0-0 (версия 1 подверсия
> 0-0) то будет правильной именно:

Понял о чем ты.
Согласен на все 100, но!!!
Но тут я как раз о сортировке проводника и рассказываю, как о украшательстве.
Понятно что применять ее повсеместно будет категорической ошибкой.


 
Розалия Самойловна   (2013-06-01 15:43) [17]

Удалено модератором


 
Rouse_ ©   (2013-06-01 15:51) [18]


> Rouse_ ©   (01.06.13 15:26) [14]

Готово, кстати благодаря тебе выцепил ошибку с числами состоящими из множества нулей. Респект :)


> Розалия Самойловна   (01.06.13 15:43) [17]
> А если это не число, а код, как в моем примере ? Почему
> какая-то программа должна решать за меня ?

Тут видишь в чем дело, какая-то там программа за тебя ничего решить не может, ибо этот алгоритм должен быть применен разработчиком этой программы.
И вот вопрос, зачем он его применил не в том месте где надо, нужно задавать непосредственно разработчику, а не мне :)

Ну а за картинку твой пост придется грохнуть, увы...


 
Розалия Самойловна   (2013-06-01 15:55) [19]


> Ну а за картинку твой пост придется грохнуть, увы...

Так давно уже говориться - приделайте к функционалу тег <spoiler> - как раз для таким моментов ;)


 
Rouse_ ©   (2013-06-01 15:57) [20]

Ну это-ж не ко мне...


 
Юрий Зотов ©   (2013-06-01 16:00) [21]


> Розалия Самойловна   (01.06.13 15:43) [17]

Дык... Розыч ведь так и сразу написал, что это бантик. И ежу понятно, что способ сортировки может зависеть от контекста. Не зря же всякие там CustomSort придуманы - пишем свой компаратор, и все ОК.

PS
А Лева шикарный...
:o)


 
брат Птибурдукова   (2013-06-01 16:37) [22]


> Rouse_ ©   (01.06.13 14:57) [7]
Печален я и скорбен головою во времена оны, когда по субботам отрабатывать приходится. Не сразу доходит, что в «ММП» М означает Москву.


 
Rouse_ ©   (2013-06-01 16:45) [23]


> брат Птибурдукова   (01.06.13 16:37) [22]
> Печален я и скорбен головою во времена

Во ты выдал :)


 
turbouser ©   (2013-06-01 18:12) [24]


>
> Rouse_ ©   (01.06.13 14:18)
>
> После вчерашнего мини ММР

А где доклад и фотки?


 
Rouse_ ©   (2013-06-01 18:33) [25]


> turbouser ©   (01.06.13 18:12) [24]
> А где доклад и фотки?

Доклада не будет (собрались, погудели, разошлись - че там описывать-то?), фотки готовлю (но блин лениво сильно).
Сегодня вечером или завтра днем выложу на http:/mmp.flat-design.ru


 
robt5   (2013-06-01 20:09) [26]

как насчот кто быстрей ? твоя или виндовая?


 
Rouse_ ©   (2013-06-01 21:06) [27]


> robt5   (01.06.13 20:09) [26]
> как насчот кто быстрей ? твоя или виндовая?

Хм, честно говоря не проверял. Моя реаллоков не использует (за исключением приведения к нижнему регистру) а дальше банальный курсор.
Я свой вариант делал, опираясь на родную реализацию CompareString, правда не стал заморачиваться с разворачиванием циклов.
Думаю если и медленнее, то на какие-то копейки...


 
Юрий Зотов ©   (2013-06-01 21:09) [28]

> брат Птибурдукова   (01.06.13 16:37) [22]

Печален я и скорбен головою,
И на луну по вечерам я вою...
:o)


 
Rouse_ ©   (2013-06-01 21:17) [29]


> robt5   (01.06.13 20:09) [26]
> как насчот кто быстрей ? твоя или виндовая?

Ан нет, проверил, моя существенно медленней...


 
robt5   (2013-06-02 18:24) [30]


> Rouse_ ©   (01.06.13 21:17) [29]

нафига там CharInSet функцией сделано? этож бред


 
antonn ©   (2013-06-02 19:56) [31]


> Понял о чем ты.
> Согласен на все 100, но!!!
> Но тут я как раз о сортировке проводника и рассказываю,
> как о украшательстве.

ну как сказать, я наоборот везде где сортирую строки пытаюсь эту "виндовую сортировку" сделать


 
Rouse_ ©   (2013-06-02 20:25) [32]


> нафига там CharInSet функцией сделано?

Код изначально писался на D2010, там используется именно функция, в противном случае будет Warning


 
Jeer ©   (2013-06-02 23:29) [33]

"Отшумели винты навсегда, навсегда.."

P.S.
Да я до сих пор на D7 и хрен меня оттуда сковырнешь:)


 
robt5   (2013-06-03 09:43) [34]


> Rouse_ ©   (02.06.13 20:25) [32]

использование подобных "функций" это удел батонокидателей
должно быть чистое логическое условие  ( c > "/" ) and ( c < ":" ), без всяких множеств
кроме того основной тормоз тут скорей всего это AnsiLowerCase ибо неправильно используется
+можно еще пару оптимизаций алгоритмических применить
вот тогда будет норм


 
brother ©   (2013-06-03 09:54) [35]

> это AnsiLowerCase

как тогда приводить к нижнему регисру быстрее?


 
antonn ©   (2013-06-03 10:52) [36]

можно хранить копию строки в нижнем регистре чтобы постоянно не использовать функцию


 
Дмитрий СС   (2013-06-03 11:21) [37]

Простите за оффтопик, может кто-то знает как сделать в проводнике, чтобы сортировка по дате выдавала файлы и папки вперемешку, а не сначала папки, потом файлы?


 
antonn ©   (2013-06-03 11:54) [38]


> Простите за оффтопик, может кто-то знает как сделать в проводнике,
>  чтобы сортировка по дате выдавала файлы и папки вперемешку,
>  а не сначала папки, потом файлы?

в каком проводнике? у меня в Вин7 (и 2008 сервер) как раз такая сортировка, как бы ее отключить... а на ХР папки и файлы отдельно


 
Sha ©   (2013-06-03 11:58) [39]

> Rouse_

Нулевое значение - это частный случай лидирующих нулей, хорошо бы их тоже обрабатывать.

1
01
001
0001
00001
...


 
Дмитрий СС   (2013-06-03 12:02) [40]


> в каком проводнике? у меня в Вин7 (и 2008 сервер) как раз
> такая сортировка, как бы ее отключить... а на ХР папки и
> файлы отдельно

И у меня win7, а можешь скриншот прислать?


 
Sha ©   (2013-06-03 12:05) [41]

Запостил и, кажется, понял, зачем MS так с нулями обходится.
Они смотрят на имя файла как на десятичную дробь:
1.2
2.03
2.3


 
antonn ©   (2013-06-03 12:16) [42]


>
> И у меня win7, а можешь скриншот прислать?

это чтоли? http://antonn.com/fh/store/3wboph7h.jpg


 
antonn ©   (2013-06-03 12:18) [43]

однако далеко не все папки так сортируются, некоторые привычно раздельно


 
Дмитрий СС   (2013-06-03 12:26) [44]


> однако далеко не все папки так сортируются, некоторые привычно
> раздельно

Да даже на твоем примере - одна дата не в кассу.

Мне хочется чтобы в папке Загрузки файлы и папки были исключительно по времени. Скачал архив, распаковал - папка и архив рядом и на самом верху.

В общем не сортировка, а какая то загадка.


 
Inovet ©   (2013-06-03 12:28) [45]

> [44] Дмитрий СС   (03.06.13 12:26)

Пользуйся FAR.:)


 
antonn ©   (2013-06-03 12:42) [46]


>
> Да даже на твоем примере - одна дата не в кассу.

это скриншот неудачный, но я точно помню что не раз бился с такой сортировкой когда "синхронизировал" две папки с разных компов и там файлы с папками были вперемежку


 
Rouse_ ©   (2013-06-03 12:43) [47]


> использование подобных "функций" это удел батонокидателей
> должно быть чистое логическое условие  ( c > "/" ) and (
> c < ":" ), без всяких множеств

И так нормально.


> Sha ©   (03.06.13 11:58) [39]
> > Rouse_
>
> Нулевое значение - это частный случай лидирующих нулей,
> хорошо бы их тоже обрабатывать.
>
> 1
> 01
> 001
> 0001
> 00001

Хм, в принципе да, но как-то не так смотрится...

Поправить то в принципе просто:

     //if S1Int = 0 then
     if (S1Cursor^ = S2Cursor^) and (S1Cursor^ = #0) then


 
Sha ©   (2013-06-03 12:50) [48]

> Rouse_
> Хм, в принципе да, но как-то не так смотрится...


Ты уж определись, как тебе так.
Так, как MS, или не так )


 
Rouse_ ©   (2013-06-03 12:59) [49]

В MS задом на перед.

А тут получается вот такая ситуация (вой вариант алго с учетом нулей):

0
1
01
0001
001_b
01_a
2

хотя по логике надо бы

0
01
01_a
001
001_b
0001
1
2

короче есть еще где подумать :)


 
Sha ©   (2013-06-03 13:07) [50]

значит условие [47] надо помениять, чтоб учитывать длину числа


 
Rouse_ ©   (2013-06-03 14:18) [51]


> Sha ©   (03.06.13 13:07) [50]

И длину числа и количество нулей, для получения приемливого результата.

0
00
01
01_b
000
001
001_a
0001
1

2

В итоге можно сделать вот так:

function CompareStringOrdinal(const S1, S2: string): Integer;
var
 S1IsInt, S2IsInt: Boolean;
 S1Cursor, S2Cursor: PChar;
 S1Int, S2Int, Mutiplier, S1ZeroCount, S2ZeroCount, S1IntLength, S2IntLength: Integer;
 SingleByte: Byte;
begin
 // Проверка на пустые строки
 if S1 = "" then
   if S2 = "" then
     Exit(0)
   else
     Exit(-1);

 if S2 = "" then Exit(1);

 S1Cursor := @AnsiLowerCase(S1)[1];
 S2Cursor := @AnsiLowerCase(S2)[1];

 while True do
 begin
   // проверка на конец первой строки
   if S1Cursor^ = #0 then
     if S2Cursor^ = #0 then
       Exit(0)
     else
       Exit(-1);

   // проверка на конец второй строки
   if S2Cursor^ = #0 then Exit(1);

   // проверка на начало числа в обоих строках
   S1IsInt := CharInSet(S1Cursor^, ["0".."9"]);
   S2IsInt := CharInSet(S2Cursor^, ["0".."9"]);
   if S1IsInt and not S2IsInt then Exit(-1);
   if not S1IsInt and S2IsInt then Exit(1);

   // посимвольное сравнение
   if not (S1IsInt and S2IsInt) then
   begin
     if S1Cursor^ = S2Cursor^ then
     begin
       Inc(S1Cursor);
       Inc(S2Cursor);
       Continue;
     end;
     if S1Cursor^ < S2Cursor^ then
       Exit(-1)
     else
       Exit(1);
   end;

   // вытаскиваем числа из обоих строк и сравниваем
   S1Int := 0;
   Mutiplier := 1;
   S1ZeroCount := 0;
   S1IntLength := 0;
   repeat
     Inc(S1IntLength);
     SingleByte := Byte(S1Cursor^) - Byte("0");
     if (SingleByte = 0) and (S1Int = 0) then
       Inc(S1ZeroCount); // запоминаем количество нулей предшествующих числу
     S1Int := S1Int * Mutiplier + SingleByte;
     Inc(S1Cursor);
     Mutiplier := 10;
   until not CharInSet(S1Cursor^, ["0".."9"]);

   S2Int := 0;
   Mutiplier := 1;
   S2ZeroCount := 0;
   S2IntLength := 0;
   repeat
     Inc(S2IntLength);
     SingleByte := Byte(S2Cursor^) - Byte("0");
     if (SingleByte = 0) and (S2Int = 0) then
       Inc(S2ZeroCount); // запоминаем количество нулей предшествующих числу
     S2Int := S2Int * Mutiplier + SingleByte;
     Inc(S2Cursor);
     Mutiplier := 10;
   until not CharInSet(S2Cursor^, ["0".."9"]);

   // Если длина числел одинаковая, сравниваем обычным способом
   if S1IntLength = S2IntLength then
   begin
     if S1Int = S2Int then
       Continue;

     if S1Int < S2Int then
       Exit(-1)
     else
       Exit(1);
   end;

   // в противном случае, если оба числа начинаются с нулей,
   // то число, у которого нулей меньше идет первым
   if (S1ZeroCount <> 0) and (S2ZeroCount <> 0) then
   begin
     if S1ZeroCount < S2ZeroCount then Exit(-1);
     if S1ZeroCount > S2ZeroCount then Exit(1);
   end;

   // если оба числа равны, то проверяем на наличие нулей перед одним из чисел
   // если такое число находится - оно идет первым
   if S1Int = S2Int then
   begin
     if S1ZeroCount > S2ZeroCount then Exit(-1);
     if S1ZeroCount < S2ZeroCount then Exit(1);
     Continue;
   end;

   // ну а если не равны, то то котое меньше идет первым
   if S1Int < S2Int then
     Exit(-1)
   else
     Exit(1);
 end;
end;


Но такая сортировка спорная, поэтому обновлять наверное не буду :)


 
Sha ©   (2013-06-03 14:26) [52]

> Rouse_
> Но такая сортировка спорная, поэтому обновлять наверное не буду :)


Мне кажется отсюда следует, что у MS сортировка правильная )


 
Rouse_ ©   (2013-06-03 14:41) [53]


> Мне кажется отсюда следует, что у MS сортировка правильная
> )


у них так:

0000
000
000_A
000_B
00
0
1
2
10
20

С нулями перегиб...


 
Sha ©   (2013-06-03 14:50) [54]

Это нормально, если считать, что справа неуместилась (вывалилась за отведенное место) значащая цифра дробного числа .0000х

Как я понимаю, у них логика следующая.
Число считается целым, если начинается не с нуля, иначе - дробным.

Подробнее алгоритм сравнения выглядит так:
1. Если первая цифра числа не нуль и длины чисел разные, то больше то, что длиннее.
2. Иначе посимвольное сравнение.


 
Sha ©   (2013-06-03 15:01) [55]

* не уместилась

можно также считать, что эта цифра совсем маленькая, меньше 1 ))


 
Дмитрий СС   (2013-06-04 12:43) [56]

Может если число начинается с нуля, сортировка МС считает что пользователь специально так сделал для правильной сортировки?


 
pasha_golub ©   (2013-06-05 10:35) [57]

Не думал я, Саня, что возлияния на тебя так могут повлиять. Что дальше? Пузырёк изобретёшь? ;)


 
Юрий Зотов ©   (2013-06-05 18:48) [58]


> pasha_golub ©   (05.06.13 10:35) [57]
>  Что дальше? Пузырёк изобретёшь? ;)

После 22-х - изобретение вполне достойное.


 
Rouse_ ©   (2013-06-05 19:35) [59]


> pasha_golub ©   (05.06.13 10:35) [57]
> Не думал я, Саня, что возлияния на тебя так могут повлиять.
>  Что дальше? Пузырёк изобретёшь? ;)

Паша, не нужно было дышать на меня сивухой хохляцкой, её аромат дал о себе знать :)


> Юрий Зотов ©   (05.06.13 18:48) [58]
> После 22-х - изобретение вполне достойное.

Сморя по какой пузырек речь, Менделеев оть аще спал, но придумал-же :)


 
Розалия Самойловна   (2013-06-06 13:20) [60]


> pasha_golub ©   (05.06.13 10:35) [57]
> Паша, не нужно было дышать на меня сивухой хохляцкой, её аромат дал о себе знать :)

Павел, Вы разве еще бухаете ?


 
Розалия Самойловна   (2013-06-06 13:36) [61]


> Юрий Зотов ©   (01.06.13 16:00) [21]
> Дык... Розыч ведь так и сразу написал, что это бантик. И ежу понятно, что способ сортировки может зависеть от контекста.

Юрий.
В том то и дело, что этот вид сортировки имеет только академическое применение. Или другими словами - таки бантик.
Ведь основная претензия с моей стороны была в том, что сущности, а именно строка и число, искусственно разделяются, проводиться отдельная сортировка по числу, а потом соединяются вновь. Но гораздо проще хранить эти сущности отдельно и соединять только при отображении, а не применять псевдо-ИИ.



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

Текущий архив: 2013.11.24;
Скачать: CL | DM;

Наверх




Память: 0.64 MB
Время: 0.007 c
11-1248772086
Антон Кивва
2009-07-28 13:08
2013.11.24
Не могу скомпилировать проект.


15-1370464203
Юрий
2013-06-06 00:30
2013.11.24
С днем рождения ! 6 июня 2013 четверг


11-1248467365
Dy1
2009-07-25 00:29
2013.11.24
WMI


2-1360966465
Anetik
2013-02-16 02:14
2013.11.24
Поиск в таблице


2-1360945552
alexdn
2013-02-15 20:25
2013.11.24
FastSize