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

How to force jumps with std::next_permutation

是否可以操纵当前排列序列以跳过(在我的情况下)"useless" 个序列?

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

一个例子:

1 2 3 4 5 6 7 ...

1 3 2 4 5 6 7 ...

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

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

例如,在上面的例子中,知道第 2 个位置的 2 是无效的,你可以编写代码来交换 2 和 3,并确保随后实现的排列是 3 在该位置可能的最小排列,等等。

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

是的,这是可能的,一旦您了解了 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 显然是下一个有效的排列。

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