如何使用std :: next_permutation强制跳转

时间:2015-07-20 06:18:53

标签: c++ c++11 permutation

是否可以操纵当前的排列顺序以便跳过(在我的情况下)"无用的"测序

如果这不可能,那么排列迭代的自定义实现是否与std :: next_permutation一样快?

一个例子:

1 2 3 4 5 6 7 ...

1 3 2 4 5 6 7 ...

检测" 2"在第二个位置是无效的,导致跳过以" 1,2"开头的每个排列。

2 个答案:

答案 0 :(得分:1)

您必须为此编写一些自定义规则。一个聪明的方法就是编写一个代码,只要你有一组无效的排列,你就可以跳转到下一个有效的排列。

例如,在上述情况下,知道第二个位置的2是无效的,您可以将代码写入交换2和3,并确保随后实现的排列是在该位置使用3的最小排列,并且等等。

另外,如果您正在编写自己的next_permuation实现,请确保内部功能与next_permutation的内部功能接近。您可以在此处阅读:std::next_permutation Implementation Explanation

答案 1 :(得分:0)

是的,这是可能的,一旦你理解了next_permutation的工作方式,这并不难。

总之,有N! N项的排列。但是,只有其中一个被排序。例如,1 2 3 4 5 6 7是5040个排列中的第一个。作为字符串(按字典顺序)查看,下一个排列是在此之后直接排序的排列:1 2 3 4 5 7 6。特别是,前5个元素没有改变。 next 置换会改变第5个元素,因为最后2个元素的顺序相反。

因此,在您的情况下,一旦您发现非法排列,您必须按排序顺序明确计算下一个合法排列。如果1 2是唯一的非法前缀,那么1 3 2 4 5 6 7显然是下一个有效的排列。

一般情况下,查看您的非法模式,确定您必须增加的位置,因为它们违反了约束条件,并为这些位置提供下一个有效值(如果您的模式足够小,你可以蛮力这个)。然后按排序顺序填写剩余的数字。