不同长度的排列

时间:2011-03-22 17:54:02

标签: c++ recursion permutation

  

可能重复:
  Algorithm to return all combinations of k elements from n

我想要做的是生成不同长度的所有1-9个排列。例如,长度为1的所有排列都是简单的 {1}, {2}, {3}, {4} ..等等。 长度为2的排列为:{1,2}, {1,3}, {1,4} .. 到目前为止,我一直在使用std::next_permutation(),但在这种情况下它不会完成任务。

有没有办法在不使用递归的情况下解决这个问题?如果不是,并且你提供任何代码我会非常感激,如果你能向我解释,因为我现在正在努力进行递归,特别是我自己实现递归解决方案。提前谢谢。

2 个答案:

答案 0 :(得分:0)

我将使用的方法从hakmem 175开始,即找到具有相同位数的下一个更高的数字。 所以,假设您在10个数字中编码一个int(从第0位到第9位) 这意味着你必须从1循环到10并使用第一个数字来启动你的int,这个数字将近似于你的对。

ex:for {1},{2} ... start int将是2 ^ 0     对于{1,2} {1,3} ...,start int将是2 ^ 0 + 2 ^ 1 等等。

之后你必须创建一个解释数字的方法(检查是否设置了一个位,然后相应的数字将出现在序列中)。

之后调用下一个号码的hakmems方法:

unsigned nexthi(unsigned a) {
  unsigned c = (a & -a);
  unsigned r = a+c;
  return (((r ^ a) >> 2) / c) | r);
}

并继续循环,直到没有数字。

并转到下一个位(1-> 10)

我建议您使用hakmem方法来了解它是如何工作的,如果您了解一些关于位的内容,那么实现很容易。

答案 1 :(得分:0)

void permute(std::vector<int>& digits, int length) {
    if (length == 0) {
        std::cout << "{";
        for (int i = 0; i < digits.length; i++) {
            std::cout << digits[i] << ",";
        }
        std::cout << "}" << std::endl;
        return;
    }

    for (int i = 0; i < 9; i++) {
        std::vector<int> newDigits(digits);
        newDigits.push_back(i);
        permute(newDigits, length -1);
    }
}

在main中调用此

std::vector<int> digits;
permute(digits, 10); // For 10 digit permutations. 

现在,如果你想获得长度为1,2 ... n的排列,那么你所要做的就是将permute函数放在循环中。

请注意,这不是最有效的实现。但我认为这应该清楚地说明递归。