string s1, s2;
int res;
s1 = "CSK."; s2 = "CSK-";
res = CompareTo(s1, s2);
Console.WriteLine(res);
s1 = "CSK.S"; s2 = "CSK-V";
res = CompareTo(s1, s2);
Console.WriteLine(res);
Результат
1
-1
Я ожидал не такое поведение. Получается, длина строки влияет на результат сравнения или вес последних символов больше веса первых символов?
Вопрос 1: Как мне добиться, чтобы на выходе было 1, 1 ну или -1, -1?
Вопрос 2: Почему я получаю такой результат?
Здравствуйте, WolfHound, Вы писали:
WH>Линуховый sort согласен с C# WH>
WH>CSK-
WH>CSK.
WH>CSK.S
WH>CSK-V
WH>
WH>Это уже становится интересно
В Java — не согласен:
Str: CSK-
Str: CSK-V
Str: CSK.
Str: CSK.S
Похоже, что в Линуксовом сорте и C# сделана оптимизация — сначала сравниваются длины строк. В Java и С++ же используется полное лексиографическое сравнение.
Здравствуйте, Cyberax, Вы писали:
C>Похоже, что в Линуксовом сорте и C# сделана оптимизация — сначала сравниваются длины строк. В Java и С++ же используется полное лексиографическое сравнение. C>В общем, просто разные подходы.
Тут нужно еще учитывать что "-" < "."
Таким образом должно быть как минимум так
CSK-
CSK.
CSK-V
CSK.S
А не так
CSK-
CSK.
CSK.S
CSK-V
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Cyberax, Вы писали:
C>Может они с концов начинают сравнивать (есть такая оптимизация)?
Может быть все что угодно, я не смог понять, где именно эта особенность заложена в методе NativeCompareInfo::CompareString.
И потом, о какой оптимизации речь? При лексикографическом сравнении нужно начинать с начала просто по определению. И еще, для строк a, ax, b, bx такого эффекта нет. Так что не знаю, в чем дело.
Здравствуйте, Mab, Вы писали:
C>>Может они с концов начинают сравнивать (есть такая оптимизация)? Mab>Может быть все что угодно, я не смог понять, где именно эта особенность заложена в методе NativeCompareInfo::CompareString. Mab>И потом, о какой оптимизации речь? При лексикографическом сравнении нужно начинать с начала просто по определению. И еще, для строк a, ax, b, bx такого эффекта нет. Так что не знаю, в чем дело.
Почитал доку на MSDN. Тогда еще возможен вариант с глючащей CultureInfo.
Здравствуйте, Аноним, Вы писали:
А>Я ожидал не такое поведение. Получается, длина строки влияет на результат сравнения или вес последних символов больше веса первых символов? А>Вопрос 1: Как мне добиться, чтобы на выходе было 1, 1 ну или -1, -1? А>Вопрос 2: Почему я получаю такой результат?
Используйте
A>И результат будет ожидаемым
Это мы уже выяснили. Пока остается непонятным нежелание дотнета выполнять лексикографическую сортировку при всех остальных способах сравнения.
Честно говоря, мне это непонятно. Свойства лексикографической сортировки очень удобны; ordinal, если я правильно понял, тупо сравнивает номера Code Point, что далеко не всегда соответствует поставленной цели.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Пока остается непонятным нежелание дотнета выполнять лексикографическую сортировку при всех остальных способах сравнения.
Народ хватит паниковать:
SQL Server 2005)
select
txt
from
(
select 'CSK.' as txt
union all
select 'CSK-'
union all
select 'CSK.S'
union all
select 'CSK-V'
) t
order by txt
Результат:
CSK-
CSK.
CSK.S
CSK-V
Это видимо правила такие сортировки со знаками препинания, а не очередной баг в майкрософт.
string s1, s2;
int res;
s1 = "CSK."; s2 = "CSK-";
res = CompareTo(s1, s2);
Console.WriteLine(res);
s1 = "CSK.S"; s2 = "CSK-V";
res = CompareTo(s1, s2);
Console.WriteLine(res);
>Результат
1
-1
>Я ожидал не такое поведение. Получается, длина строки влияет на результат сравнения или вес последних символов больше веса первых символов? >Вопрос 1: Как мне добиться, чтобы на выходе было 1, 1 ну или -1, -1? >Вопрос 2: Почему я получаю такой результат?
Фишка в том, что по умолчанию при сравнении строк в .NET символы апострофа и дефиса имеют очень малые веса. Фактически они учитываются только если строки совпадают за исключением этих символов.
Вот выдержка из MSDN:
The .NET Framework uses three distinct ways of sorting: word sort, string sort, and ordinal sort. Word sort performs a culture-sensitive comparison of strings. Certain nonalphanumeric characters might have special weights assigned to them; for example, the hyphen ("-") might have a very small weight assigned to it so that "coop" and "co-op" appear next to each other in a sorted list. String sort is similar to word sort, except that there are no special cases; therefore, all nonalphanumeric symbols come before all alphanumeric characters. Ordinal sort compares strings based on the Unicode values of each element of the string.
Изменить способ сортировки можно при помощи перечисления CompareOptions.
Чтобы включить "ordinal sort", использовать CompareOptions.Ordinal.
Чтобы включить "string sort", использовать CompareOptions.StringSort.
Меня слегка удивляет, что по умолчанию включено "word sort", а не "string sort"... Например, как уже тут говорили, SQL Server по умолчанию сортирует обычным способом. А поскольку SQL Server и .NET — это стандартная связка, то получаем красиво и со вкусом разложенные грабли.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, yg, Вы писали: S>Обалдеть! Посыпаю голову своего невежества пеплом твоей эрудиции. S>А где именно в MSDN это написано?