what I want to do is check an array of bools to see if 3 or more of them have been set to true. The only way I can think to do this is using a if statement for each possible combination of which there is lots because there are ten bools. Dose anybody have any suggestions on how best to do this.
8 Answers
This would be the easiest way:
std::count(bool_array, std::end(bool_array), true) >= 3
Only problem is it keeps counting even after it has found 3. If that is a problem, then I would use sharptooth's method.
side note
I've decided to fashion an algorithm in the style of std::all_of/any_of/none_of for my personal library, perhaps you will find it useful:
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;
}
For your purpose, you would use it like this:
n_or_more_of(bool_array, std::end(bool_array), [](bool b) { return b; }, 3);
2 Comments
std:: as I did above. Or you have a using declaration in your file.The much easier way would be to loop through the array:
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;
Comments
Whenever you are setting an array element into TRUE value, you can increment a global counter. This will be the simplest way. At any point in your code, the global array will tell you the number of TRUE elements in the Array.
Another thing - if you are keeping upto 32 bool values, you can use a single int variable. int is 32 bits (in Win32) and you can store 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) )
2 Comments
You can loop through and build a bit-mask representation of the array, then you can compare against up to CHAR_BIT * sizeof (unsigned long) in parallel:
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
{
}
This assumes that you're looking for patterns, not just want to count the number of true flags in the array.
Comments
Just loop through the array counting the number of bools set to 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;
}
Then call it like so
hasNTrue(myArray, 3, myArrayLength);