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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.63 MB
Время: 0.004 c
15-1370594895
Новичок 4444
2013-06-07 12:48
2013.11.24
Как стать программистом ?


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


2-1360930799
Camaro
2013-02-15 16:19
2013.11.24
Считывание данных со стрима


15-1370348553
"Добрый Сок"
2013-06-04 16:22
2013.11.24
Поскажите задачку, не соображу


15-1370336442
Дмитрий СС
2013-06-04 13:00
2013.11.24
Улучшители IDE Delphi 7





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский