Sort char * С особыми (немецкими) символами? - PullRequest
2 голосов
/ 31 октября 2010

У меня проблема в том, что мне нужно отсортировать целую кучу указателей на символы, но у них есть специальные символы. Мне удалось получить процедуру сортировки так:

std::sort(dict_.begin(), dict_.end(), comp);

bool comp(NumPair& a, NumPair& b)
{
    return boost::lexicographic_compare(a.pFirst, b.pFirst);
}

Это прекрасно работало, за исключением того, что все специальные немецкие символы были отсортированы раньше всех остальных. Мой учитель (да, это относится к домашнему заданию), однако, хочет, чтобы они были отсортированы в конце. Awesome!

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

return boost::lexicographic_compare(a.pFirst, b.pFirst, locale("german"));

Не сработало! Итак:

bool comp()
{
    setlocale(LC_ALL, "");
    return boost::lexicographic_compare(a.pFirst, b.pFirst);
}

Не сработало!

Если они у вас есть, я хотел бы услышать некоторые другие идеи, которые могли бы действительно работать.

Обновление:

По запросу, некоторые примеры ввода и вывода:

// Some entries
dict_.push_back( NumPair ( "öffnen", "to open" ) );
dict_.push_back( NumPair ( "überraschen", "to surprise" ) );
dict_.push_back( NumPair ( "wünschen", "to wish, to desire, to want" ) );
dict_.push_back( NumPair ( "widersprechen", "to contradict_" ) );

// NumPair ctor.
NumPair( const char *pFirst, const char *pSecond )
{
    /* Deep copy of pFirst and pSecond */
}

Вывод после результата:

öffnen
überraschen
wünschen
widersprechen

Ответы [ 2 ]

3 голосов
/ 31 октября 2010

Возможно, вы захотите показать больше своего кода, например, какие именно строки вы используете, которые вызывают эту проблему.Я легко могу отсортировать набор немецких слов, и любые слова, начинающиеся со специальных немецких символов, не относящихся к ASCII, упорядочиваются в конце.Это происходит даже без каких-либо специальных настроек немецкой локали, поскольку в Unicode символы не-ASCII имеют более высокие значения кодовой точки, чем символы ASCII.

Например:

setlocale(LC_ALL, "");

std::vector<std::wstring> vec;
vec.push_back(L"Hallo");
vec.push_back(L"Morgen");
vec.push_back(L"Zebra");
vec.push_back(L"Abend");
vec.push_back(L"Übertragens");
vec.push_back(L"Buchen");

std::sort(vec.begin(), vec.end());
for (std::vector<std::wstring>::iterator it = vec.begin(); it != vec.end(); ++it)
    std::wcout << *it << std::endl;

Это выводит:

Abend
Buchen
Hallo
Morgen
Zebra
Übertragens

Обратите внимание на использование wide символьных строк.Поскольку процедуры лексикографического сравнения сравнивают посимвольно, вам необходимо использовать широкие символы, иначе функция сравнения в конечном итоге будет сравнивать строку byte-byte вместо посимвольного символа.Это приведет к недопустимому сравнению, поскольку не каждый символ Unicode может храниться в одном байте.Например, специальные символы немецкого языка составляют 2 байта в UTF-8, поэтому вам необходим тип данных, способный содержать диапазон от 0x00 до 0xFFFF в одном элементе.На большинстве платформ для этого достаточно wchar_t.

(Также обратите внимание, что не рекомендуется включать в исходный код не-ASCII символы. Вместо этого используйте «универсальные коды символов». Я просто используюне-ASCII источник здесь для ясности.)

1 голос
/ 01 ноября 2010

Я бы рекомендовал использовать функцию CompareString, если вы используете Windows.http://msdn.microsoft.com/en-us/library/dd317759

Локали очень подвержены ошибкам.Кроме того, многопоточность вызывает проблемы, если вы используете локали.

...