Страницы

Поиск по вопросам

воскресенье, 15 декабря 2019 г.

Сортировка строк и буква ё с++

#cpp #visual_studio #строки #сортировка


Нужно отсортировать слова, например: ёжик, Азбука, аромат, Ёж. Проблема в том, что
буква ё не сортируется. 

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main() {

    int element;
    string number;
    cin >> element;
    auto l = list();
    for (int i = 0; i < element; i++) {
        cin >> number;
        l.push_back(number);
    }

    l.sort();

    for (auto iterator = l.begin(); iterator != l.end(); ++iterator)
    {
        cout << *iterator << endl;
    }


    return 0;
}

    


Ответы

Ответ 1



При сортировке списка из string строки сравниваются по-символьно (побайтно). В зависимости от типа кодирования байт будут разные результаты сравнения. Во всех популярных кодировках, а именно в Unicode, CP866 (DOS), CP1251 (Windows) во всех у них буква Ё/ё стоят где-то в отдельном месте от алфавита, это означает сравнение букв не будет давать порядок как в эталонном русском алфавите. Но проблема решаема, т.к. у функции сортировки можно указать свою функцию сравнения элементов. l.sort([](string const & l, string const & r)->bool{ /* Сравнить l и r */ }); при этом нужно реализовать код внутри так чтобы сравнить две строки l и r учитывая специфику буквы Ё/ё, код должен возвращать true если l < r иначе false. Также чтобы решить проблемы с кодировками можно просто в каком то виде вначале прочитать строки, а потом их сконвертировать в Unicode и уже в юникоде делать сравнения, либо привязаться к какой то кодировке, это не важно в какой кодировке Ё/ё по особому сравнивать. Вот привожу почти весь нужный код, подходит для строк в кодировках CP866 и CP1251 (для юникода тоже вполне может подойти только вместо char нужно uint32_t или char32_t): // Где-то выше определить функцию CharOrder. inline uint32_t CharOrder(char c) { if (c == 'ё') return uint32_t(uint8_t('е')) * 2 + 1; if (c == 'Ё') return uint32_t(uint8_t('Е')) * 2 + 1; return uint32_t(uint8_t(c)) * 2; } .... // Где нужно сортировать список l из строк, написать. l.sort([](std::string const & a, std::string const & b)->bool{ return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b)->bool{ return CharOrder(a) < CharOrder(b); }); });

Ответ 2



#include #include #include #include #include #include template static void PrintList(const std::list& l) { std::cout << "List: "; for (auto iterator = l.begin(); iterator != l.end(); ++iterator) { std::cout << *iterator << " "; } std::cout << std::endl; } int main(int argc, const char * argv[]) { system("chcp 1251"); std::list l = { "ёлка", "Еда", "аббат", "жеод" }; PrintList(l); l.sort(std::locale("")); PrintList(l); return 0; }

Комментариев нет:

Отправить комментарий