如何使用 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 足够小,你可以暴力破解它)。然后按排序顺序填写剩余的数字。
是否可以操纵当前排列序列以跳过(在我的情况下)"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 足够小,你可以暴力破解它)。然后按排序顺序填写剩余的数字。