Как бы вы посчитали вручную на бумаге? Вы бы проверили последнюю цифру. Если это 0, вы устанавливаете его на 1. Если это уже 1, вы устанавливаете его обратно на 0 и переходите к следующей цифре. Так что это рекурсивный процесс.
Следующая программа генерирует все возможные комбинации, изменяя последовательность:
#include <iostream>
template <typename Iter>
bool next(Iter begin, Iter end)
{
if (begin == end) // changed all digits
{ // so we are back to zero
return false; // that was the last number
}
--end;
if ((*end & 1) == 0) // even number is treated as zero
{
++*end; // increase to one
return true; // still more numbers to come
}
else // odd number is treated as one
{
--*end; // decrease to zero
return next(begin, end); // RECURSE!
}
}
int main()
{
char test[] = "0000";
do
{
std::cout << test << std::endl;
} while (next(test + 0, test + 4));
}
Программа работает с любой последовательностью любого типа. Если вам нужны все возможные комбинации одновременно, просто поместите их в коллекцию, а не распечатывайте. Конечно, вам нужен другой тип элемента, потому что вы не можете поместить массивы C в вектор. Давайте используем вектор строк:
#include <string>
#include <vector>
int main()
{
std::vector<std::string> combinations;
std::string test = "0000";
do
{
combinations.push_back(test);
} while (next(test.begin(), test.end()));
// now the vector contains all pssible combinations
}
Если вам не нравится рекурсия, вот эквивалентное итеративное решение:
template <typename Iter>
bool next(Iter begin, Iter end)
{
while (begin != end) // we're not done yet
{
--end;
if ((*end & 1) == 0) // even number is treated as zero
{
++*end; // increase to one
return true; // still more numbers to come
}
else // odd number is treated as one
{
--*end; // decrease to zero and loop
}
}
return false; // that was the last number
}