Nil*_*ils 8 c++ language-agnostic algorithm haskell
如何在长度为n的位数组中生成所有可能的位组合.如果我从我的数组中的所有零开始,则有n种可能性放置第一位,并且对于这n种可能性,存在n-1种可能性来放置第二位.单位所有n位被设置为1.但到目前为止,我没有设法编程.
还有很多人指出我可以通过从0到(2 ^ n)-1计数并以二进制打印数字来做到这一点.这将是一种解决问题的简单方法,但是在这种情况下,我只是让机器计数而不是告诉它放置在哪里.我这样做是为了学习,所以我想知道如何编制一个放置方法.
fre*_*low 13
你会如何在纸上手动计算?你会检查最后一位数.如果为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));
}
Run Code Online (Sandbox Code Playgroud)
该程序适用于任何类型的任何序列.如果您需要同时进行所有可能的组合,只需将它们放入集合中而不是将它们打印出来.当然,您需要一个不同的元素类型,因为您不能将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
}
Run Code Online (Sandbox Code Playgroud)
如果你不喜欢递归,这里是一个等价的迭代解决方案:
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
}
Run Code Online (Sandbox Code Playgroud)
fre*_*low 10
这些问题在功能上很容易解决.要找到长度为n的解,首先找到长度为n-1的解,然后将"0"和"1"附加到这些解,使解空间加倍.
这是一个简单的递归Haskell程序:
comb 0 = [[]]
comb n =
let rest = comb (n-1)
in map ('0':) rest
++ map ('1':) rest
Run Code Online (Sandbox Code Playgroud)
这是一个测试运行:
> comb 3
["000","001","010","011","100","101","110","111"]
Run Code Online (Sandbox Code Playgroud)