Algorithm 从字母组中获取单词组合
我在网上搜索了很多如何做到这一点,但我没有找到我完全理解的东西 我试图通过指定每组中的字母数量,从字母数组中生成所有可能的组合,例如: 字母:Algorithm 从字母组中获取单词组合,algorithm,combinations,Algorithm,Combinations,我在网上搜索了很多如何做到这一点,但我没有找到我完全理解的东西 我试图通过指定每组中的字母数量,从字母数组中生成所有可能的组合,例如: 字母:A、B、C 长度:2 结果:AB、AC、BC (我知道也有:BA、CA和CB,但我只需要获得组,顺序无关紧要。) 例2: 字母:A、B、C、D 长度:3 结果:ABC、ACD、BCD、CDA、DAB 等等 我打算在C++中实现该算法,但是C语言、java语言和JavaScript也有欢迎的例子。 看起来很适合递归。取每个元素,并将其预先添加到剩余的组合中,
A、B、C
长度:2
结果:AB、AC、BC
(我知道也有:BA
、CA
和CB
,但我只需要获得组,顺序无关紧要。)
例2:
字母:A、B、C、D
长度:3
结果:ABC、ACD、BCD、CDA、DAB
等等
<>我打算在C++中实现该算法,但是C语言、java语言和JavaScript也有欢迎的例子。
看起来很适合递归。取每个元素,并将其预先添加到剩余的组合中,直到达到给定的深度
static List<String> func(List<String> a, Int32 depth)
{
List<String> retVal = new List<String>();
if (depth <= 0)
{
return retVal;
}
for (int i = 0; i < a.Count; i++)
{
String element = a[i];
List<String> temp = new List<String>(a);
temp.RemoveAt(i);
List<String> resultset = func(temp, depth - 1);
if (resultset.Count == 0)
{
retVal.Add(element);
}
else
{
foreach (String result in resultset)
{
retVal.Add(element + result);
}
}
}
return retVal;
}
静态列表函数(列表a,Int32深度)
{
List retVal=新列表();
如果(深度如果您以可复制的方式对它们进行排序,您将找到一种更容易生成它们的算法:
让我们不要太简单,取5个中的3个:
e d c b a
---------
x x x abc
x x x abd
x x x abe
x x x acd
x x x ace
x x x ade
x x x bcd
x x x bce
x x x bde
x x x cde
如果稍微调整一下,这应该会起作用:
void r_nCr(const unsigned int &startNum, const unsigned int &bitVal, const unsigned int &testNum) // Should be called with arguments (2^r)-1, 2^(r-1), 2^(n-1)
{
unsigned int n = (startNum - bitVal) << 1;
n += bitVal ? 1 : 0;
for (unsigned int i = log2(testNum) + 1; i > 0; i--) // Prints combination as a series of 1s and 0s
cout << (n >> (i - 1) & 1);
cout << endl;
if (!(n & testNum) && n != startNum)
r_nCr(n, bitVal, testNum);
if (bitVal && bitVal < testNum)
r_nCr(startNum, bitVal >> 1, testNum);
}
void r_nCr(const unsigned int&startNum、const unsigned int&bitVal、const unsigned int&testNum)//应使用参数(2^r)-1、2^(r-1)、2^(n-1)调用
{
unsigned int n=(startNum-bitVal)0;i--)//将组合打印为一系列1和0
cout>(i-1)和1);
cout>1,testNum);
}
解释。这被称为置换,有很多解决方案。
这是我写的一个非递归的,速度非常快(如果你在Windows上,你可能需要查找BitScanReverse而不是使用内置ctz)
似乎与非常密切相关。生成部分组可能更容易,如果您在内部始终按升序生成它们,例如:“abc”、“acd”、“bcd”、“acd”、“abd”……然后按顺序生成abc、abd、acd-啊,您得到了两次!看!这里有一个Python实现:在给定长度N到p的所有组合的情况下,尝试提出一个方法生成所有长度组合(N+1)。@sch-对不起,是的;你说得对。你的问题涉及组合(如你最初所述),另一个涉及排列。请注意,如果你在添加列表中的项目时对其进行过滤,我链接问题中的已接受答案仍应为你提供解决方案;只需创建一个ListAdd()函数,该函数对传入单词中的字符进行排序,如果尚未出现,则将其添加到列表中。谢谢!这非常有用!
#include <iostream>
#include <cstdlib>
using namespace std;
void perm(unsigned &v) { //v must be initialised with t = ( 2 << N ) - 1;
unsigned t = v | (v - 1);
v = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
}
int main (int argc, char *argv[]) {
unsigned n = argc > 1 ? atoi(argv[1]) : 3; //bins: 0..31
unsigned k = argc > 2 ? atoi(argv[2]) : 2; //things: 0 .. bins.
unsigned m = (1 << n) - 1; //bitmask is size of n (bins).
unsigned v = (1 << k) - 1; //start value - initial allocation.
do {
cout << bitset<31>(v & m) << endl;
perm(v);
} while (v < m);
return 0;
}
ABC
011 //BC
101 //AC
110 //AB