как сравнить все элементы в списке, используя unique () c ++ - PullRequest
0 голосов
/ 29 апреля 2020

Мне нужно удалить все одинаковые слова (слова совпадают, если они начинаются с одной и той же буквы). Моя функция сравнения выполняет следующее:

H  J
J  H
H  I

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

 bool compare(string a, string b) {
        cout << a.front() << "  " << b.front() << endl;
        return(a.front() == b.front());
    }
    void Fifth_task(list <string>& lst) {
        list <string> ::iterator it;
        lst.unique(compare);
        for (it = lst.begin(); it != lst.end(); ++it) {
            cout << *it << endl;
        }
    }


    int main(){
    list <string> first;
    first.push_back("Hello");
    first.push_back("Johnny");
    first.push_back("Hello");
    first.push_back("Ildar");
    Fifth_task(first);
    return 0;
    }

В итоге я должен получить 3 слова: Привет, Джонни, Ильдар Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

std::list::unique удаляет соседние дубликаты. Предикат, который вы ему даете, предназначен для сравнения равенства смежных элементов. Это не то, что вам нужно, так как вы хотите сравнить элемент со всеми предыдущими элементами.

Вместо этого вы можете использовать list::remove_if, используя набор для записи первых увиденных букв. Поэтому я бы изменил вашу Fifth_task функцию так:

void Fifth_task(std::list<std::string>& lst) {
    std::list<std::string>::iterator it;
    std::set<char> seen;
    lst.remove_if([&](const std::string& s) {
        char c = std::tolower(s[0]);
        bool remove = (seen.count(c) > 0);
        seen.insert(c);
        return remove; });

    for (it = lst.begin(); it != lst.end(); ++it) {
        std::cout << *it << std::endl;
    }
}

Рабочая версия здесь: https://godbolt.org/z/WLwQeZ

0 голосов
/ 29 апреля 2020

От cppreference , уникальная воля ...

Исключает все, кроме первого элемента из каждой последовательной группы эквивалентных элементов из диапазона

(выделено)

В примере на этой странице вызов unique() для {1,2,1,1,3,3,3,4,5,4} приведет к {1 2 1 3 4 5 4 x x x}. Обратите внимание, как дубликаты 1 и 4 не удаляются. Это потому, что они не входят в «последовательную группу».

Поэтому, чтобы все ваши слова, начинающиеся с одной и той же буквы, были в «последовательных группах», сначала отсортируйте список:

 void Fifth_task(list <string>& lst) {
    lst.sort();
    lst.unique(compare);
    // ...

Смотрите это в действии здесь: https://ideone.com/1i48nj

...