условное тестирование на равенство элементов вектора - PullRequest
1 голос
/ 03 апреля 2011

Хотя это кажется довольно простым, я не уверен в самом эффективном способе сделать это.

У меня есть два вектора:

std::vector<bool> a;
std::vector<int> b;

a.size() обязательно равно b.size().

каждый bool в a соответствует int в b.Я хочу создать функцию:

bool test(std::vector<bool> a, std::vector<int> b);

Эта функция возвращает true, если значения в a равны.Тем не менее, он учитывает только значения в a, которые соответствуют true значениям в b.

Я мог бы сделать это:

bool test(std::vector<int> a, std::vector<bool> b){
    int x;
    unsigned int i;
    for(i = 0; i < a.size(); ++i){
        if(b.at(i) == true){
            x = a.at(i);
            break;
        }
    }
    for(i = 0; i < a.size(); ++i){
        if(b.at(i) == true){
            if(a.at(i) != x){
                return false;
            }
        }
    }
    return true;
}

Но тогда мне нужно создать два цикла,Хотя первый цикл остановится на первом истинном значении, есть ли лучший способ?

Ответы [ 4 ]

3 голосов
/ 03 апреля 2011

Ваше решение выглядит достаточно хорошо для меня:

  • Каждый цикл в любом случае выполняет разные функции (поэтому вам не стоит беспокоиться о дублировании)
  • Вы не используете посторонние переменныеили флаги, которые усложняют код.

Единственные проблемы, которые я вижу:

  • Второй цикл начинается с 0 вместо того, где вы остановились.
  • Делать if(condition == true) очень некрасиво.Просто сделайте if(condition) вместо.

bool test(std::vector<int> a, std::vector<bool> b){
    int x;
    unsigned i;
    for(i = 0; i < a.size(); i++){
        if(b.at(i)){
            x = a.at(i);
            break;
        }
    }
    for(i++; i < a.size(); i++){
        if(b.at(i)){
            if(a.at(i) != x){
                return false;
        }
    }
    return true;

}

3 голосов
/ 03 апреля 2011

Вы можете сделать это за один цикл, если вы помните, видели ли вы первый элемент true в b или нет. Кроме того, вы должны взять параметры a и b по ссылке, чтобы избежать ненужного копирования. И, наконец, если вы знаете, что индексы в векторе всегда находятся в допустимом диапазоне (то есть между 0 и vector.size () - 1 включительно), вы можете использовать operator[] вместо at и добиться лучшей производительности ( at выполняет проверку диапазона, а operator[] - нет). Вот модифицированная версия вашей test функции с учетом всех вышеперечисленных пунктов:

bool test(std::vector<int> const& a, std::vector<bool> const& b){
    int x;
    bool first = true;
    for(unsigned i = 0, n = a.size(); i != n; ++i){
        if( b[i] ){
            if( first ) {
                x = a[i];
                first = false;
            }
            else if( x != a[i] ) {
                return false;
            }
        }
    }
   return true;
}
1 голос
/ 03 апреля 2011

При условии, что вы знаете, что a.size () == b.size () просто создайте один цикл, который сравнивает элемент 'a' с элементом 'b' одновременно на каждой итерации.Как только вы видите, что a [i]! = B [i], вы знаете, что контейнеры не совпадают, и вы можете вырваться.

0 голосов
/ 03 апреля 2011

Я не уверен на 100%, что знаю, что вы хотите сделать, но прямое сравнение, если вы знаете, что у вас равный размер

std::equal(a.begin(), a.end(), b.begin(), std::equal_to<bool>())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...