Как сравнить два последовательных элемента в списке c ++ - PullRequest
0 голосов
/ 02 июля 2019

Мне нужно найти два элемента с одинаковыми полями. Они должны быть последовательными в одном и том же векторе. Мне нужно сделать это с помощью метода STL. Я пытался использовать find или find_if, но не смог этого сделать. Можете ли вы дать мне подсказку, пожалуйста?

Мой код (некоторые его части):

class Sound {
    private:
        int notePitch, length;
    public:
        Sound(int notePitch, int length) {
            this->notePitch = notePitch;
            this->length = length;
        }
        int getPitch() {
            std::cout << "Pitch: " << this->notePitch << " length: " << this->length;
            return this->notePitch;
        }
    };

Фактическая функция поиска:

std::vector<Sound>::iterator iter = masterpiece.begin();
std::vector<Sound>::iterator iterEnd = masterpiece.end();   
std::vector<Sound>::iterator it = find_if(iter, iterEnd, [](auto prev, auto next) -> bool {                 
    return prev.getPitch()  == next.getPitch(); 
});

Я получаю следующую ошибку:

c2678 binary '==' no operator found which takes a left-hand operand of type

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Стандартный алгоритм std::find_if не принимает двоичный предикат.

Вы можете использовать стандартный алгоритм std::adjacent_find с лямбда-выражением.

Функция-член getPitch должна быть объявлена ​​с квалификатором const. В этом случае вы можете использовать функцию для постоянных объектов (например, когда объект типа Sound или вектор объектов Sound передается функции, которая принимает постоянную ссылку)

Вот демонстрационная программа

#include <iostream>
#include <vector>
#include <iterator> 
#include <algorithm>

class Sound {
    private:
        int notePitch, length;
    public:
        Sound(int notePitch, int length) {
            this->notePitch = notePitch;
            this->length = length;
        }
        int getPitch() const {
//            std::cout << "Pitch: " << this->notePitch << " length: " << this->length;
            return this->notePitch;
        }
    };

int main( void )
{
    std::vector<Sound> masterpiece = { { 1, 2 }, { 2, 3 }, { 2, 4 }, { 3, 5 } };

    auto it = std::adjacent_find( std::begin( masterpiece ), std::end( masterpiece ),
                                  []( const  Sound &a, const Sound &b )
                                  {
                                    return a.getPitch() == b.getPitch();
                                  } );

    if ( it != std::end( masterpiece ) )
    {
        std::cout << "Two adjacent elements are found at position " 
                  << std::distance( std::begin( masterpiece ), it )
                  << '\n';
    }
    else
    {
        std::cout << "Two adjacent elements are found\n";
    }
}

Вывод программы

Two adjacent elements are found at position 1

Вы можете записать параметры лямбда-выражения, используя auto

[]( const auto &a, const auto &b )
{
    return a.getPitch() == b.getPitch();
}

Но в любом случае лучше объявить их как имеющие ссылочный тип const, потому что в этом случае ни один из временных объектов не будет создан, а лямбда-выражение гарантирует, что оно не изменит свои аргументы.

1 голос
/ 02 июля 2019

Используйте смежный_файл вместо find_if.Ваш код должен работать.

std::vector<Sound>::iterator it = adjacent_find (iter, iterEnd, [](auto prev, auto next) -> bool {                 
    return prev.getPitch()  == next.getPitch(); 
...