c ++ проверяет все значения массива одновременно - PullRequest
2 голосов
/ 11 января 2012

что я хочу сделать, это проверить массив bools, чтобы увидеть, установлены ли 3 или более из них в значение true.Единственный способ, которым я могу думать, - это использовать оператор if для каждой возможной комбинации, в которой есть много, потому что есть десять бул.У кого-нибудь есть какие-либо предложения о том, как лучше всего это сделать.

Ответы [ 8 ]

10 голосов
/ 11 января 2012

Это будет самый простой способ:

std::count(bool_array, std::end(bool_array), true) >= 3

Единственная проблема - он продолжает считать даже после того, как обнаружил 3. Если это проблема, то я бы использовал метод sharptooth.

примечание

Я решил создать алгоритм в стиле std::all_of/any_of/none_of для моей личной библиотеки, возможно, вы найдете его полезным:

template<typename InIt, typename P>
bool n_or_more_of(InIt first, InIt last, P p, unsigned n)
{
    while (n && first != last)
    {
        if (p(*first)) --n;
        ++first;
    }
    return n == 0;
}

Для вашей цели вы бы использовали это так:

n_or_more_of(bool_array, std::end(bool_array), [](bool b) { return b; }, 3);
8 голосов
/ 11 января 2012

Намного проще было бы перебрать массив:

int numberOfSet = 0;
for( int i = 0; i < sizeOfArray; i++ ) {
     if( array[i] ) {
        numberOfSet++;
        //early cut-off so that you don't loop further without need
        // whether you need it depends on how typical it is to have
        // long arrays that have three or more elements set in the beginning
        if( numberOfSet >= 3 ) {
            break;
        }
     }
}

bool result = numberOfSet >= 3;
1 голос
/ 11 января 2012

Всякий раз, когда вы устанавливаете элемент массива в значение ИСТИНА, вы можете увеличивать глобальный счетчик.Это будет самый простой способ.В любой точке вашего кода глобальный массив сообщит вам количество элементов TRUE в массиве.

Другое дело - если вы сохраняете до 32 значений bool, вы можете использовать одну переменную int.int - это 32 бита (в Win32), и вы можете хранить 32 bool.

char x = 0; //  00000000 // char is 8 bits

// TO SET TRUE
x = x | (1 << 4); // 00010000
x = x | (1 << 7); // 10010000

// TO SET FALSE
x = x & ~(1 << 4); // 10010000 & 11101111 => 10000000

// TO CHECK True/False
if( x & ~(1 << 4) )
0 голосов
/ 11 января 2012

Храните bool как биты в целых числах. Затем примените один из битовых хаки тидлинга .

0 голосов
/ 11 января 2012

Просто переберите массив, считая число bools, установленное в true.

/**
 * @param arr The array of booleans to check.
 * @param n How many must be true for this function to return true.
 * @param len The length of arr.
 */
bool hasNTrue(bool *arr, int n, int len) {
    int boolCounter;
    for(int i=0; i<len; i++) {
        if (arr[i]) boolCounter++;
    }
    return boolCounter>=n;
}

Затем назовите его так:

hasNTrue(myArray, 3, myArrayLength);
0 голосов
/ 11 января 2012

Вы можете выполнить цикл и построить представление массива в битовой маске, а затем сравнить до CHAR_BIT * sizeof (unsigned long) параллельно:

unsigned long mask = 0;
for (std::vector<bool>::const_iterator it = flags.begin(), end_it = flags.end();
     it != end_it;
     ++it)
{
  if (*it)
    mask |= (1 << (it - flags.begin()));
}

if (mask & (0xaa3)) // or whatever mask you want to check
{
}

Это предполагает, что вы ищете pattern , а не просто считать количество true флагов в массиве.

0 голосов
/ 11 января 2012

Почему бы просто не посчитать количество истин, а затем сделать что-то, если число равно 3 или больше:

int sum = 0;
for (int i = 0; i < length; i++){
  if (arr[i]){
    sum++;
  }
}

if (sum >= 3){
  // do something...
}
0 голосов
/ 11 января 2012

Если это массив, то вы зацикливаетесь на нем и подсчитываете количество истин.Но, боюсь, ты имеешь в виду что-то вроде рисунка, верно?

...