生成给定长度的所有可能的一和零的数组的算法
问题内容:
如何在长度为n的位数组中生成所有可能的位组合。如果我从数组中的所有零开始,那么就有n种可能性来放置第一位,而对于这n种可能性,就有n-1种可能性来放置第二位。.所有n位都被设置为1。但是到目前为止,我还没有进行编程。
也有许多人指出,我可以通过从0到(2 ^
n)-1计数并以二进制形式打印数字来实现。这将是解决问题的简便方法,但是在这种情况下,我只是让机器计数而不是告诉机器放置位置。我这样做是为了学习,所以我想知道如何编程那些放置方式。
问题答案:
您将如何在纸上手动计数?您将检查最后一位数字。如果为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
}