4

我想计算一组大小 X 的大小 Y 的所有排列。也就是说,如果我有 (1,2,3) 并且想要大小为 2, 3P2 的所有排列,它将是 (1,2) ( 1,3) (2,1) (2,3) (3,1) (3,2)。

GSL 和 C++ STL 都只提供我可以看到的 xPx。有人可以指点我一个可以做到这一点的 C/C++ 库或拼出一个快速且内存高效的算法吗?

我正在尝试解决一个非常短的密码。我已经找出了两个字母,并决定进行蛮力攻击。我有“ouglg ouyakl”,并且正在对照一本非常好的字典检查每个排列。我已经消除了 2 个字母,所以它的 24P7 或 1,744,364,160 种可能性还不错。我现在有一个 Perl 程序正在运行,所以这将是一个有趣的测试编程时间 + 运行时间的总效率。:)

(不,我不只是想要密码的答案。)

4

3 回答 3

2

我以前在需要做类似事情的代码中使用过这个库(注意它是 C++)。它有排列组合,有重复和没有重复。对于您的问题,这应该足够了(未经测试...):

std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

std::vector<int>::iterator first = v.begin(), middle = v.begin() + 2, last = v.end();

do {
    // do stuff with elements in range first...middle (but dont change them)
} while(next_partial_permutation(first, middle, last));
于 2009-11-02T22:11:40.890 回答
0

我不完全明白你关于密码的问题。但是如果你想在你的字典中找到这个词的最长排列(字谜),你可以试试他的方法。

  1. 创建您的单词的位掩码。您可能可以使用 64 位算术,因此您可以在其中放置近 3 个字母。

a-> 第一位,b-> 第二位,依此类推。如果您的“ouglg ouyakl”案例中有字,这意味着

 abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyzabcdefghijklmnop
 100000100011001000001001000000010000100100000100000000000000000000

(希望我没有错过任何东西)现在您为您的词汇表创建相同的位掩码。

当你检查词汇时,你只需要做的是

 vocabulary & ( ouglg_ouyakl ^ vocabulary)

如果您的词汇来自 ouglg_ouyakl,则此值将变为 0。

关于排列

for each permutation of numbers fom  1-n // that is 1,2 and 2,1
  for(i=0;i<end;i++)
    for(j=i+1;j<end;j++)
      SET[permutation[i]],SET[permutation[j]]

编辑:以前的解决方案不适用于 24P7。

于 2009-11-02T22:50:02.167 回答
0

您可以通过使用std::next_permutation()一个vector<bool>标志来获得组合。以从 中选择 2 个元素为例(1,2,3),将向量作为(false, true, true). 重复next_permutation()这个会给你(true, false, true)then (true, true, false),然后重新开始。

由于您想要排列而不是组合,请将每个组合映射到一组实际元素(例如(true, false, true)变为 (1, 3)),然后next_permutation()再次使用这些组合生成所有排列。

于 2009-11-02T23:55:54.047 回答