排列为数字的标准表示使用Lehmer codes 表示在factorial number system 中。这个想法是n个元素的每个排列都可以映射到n个数字的序列,其中第一个在0到(n - 1)的范围内,第二个在0到(n - 2)的范围内等。然后,这个数字序列可以在阶乘数字系统中表示为单个整数。
我相信应该可以调整这个技巧来处理排列的前缀而不是整个排列。假设您有 n 个元素,并且想要选择其中 k 个的排列。为此,首先计算部分排列的 Lehmer 码。您将得到一个由 k 个数字组成的序列,而不是得到一个由 n 个数字组成的序列。例如,给定从 a b c d e f g 提取的部分排列 c a d,您的 Lehmer 代码将如下所示:
-
c 是 a b c d e f g 的第二个(零索引)元素
-
a 是 a b d e f g 的第零个(零索引)元素
-
d 是 b d e f g 的第一个(零索引)元素
所以 Lehmer 代码将是 (2, 0, 1)。
一旦你有了这个 Lehmer 代码,你就可以尝试将它编码为一个整数。为此,您可以使用修改后的阶乘数字系统编码。具体来说,您可以尝试执行以下操作。如果你有 n 个元素并且想要其中 k 个的排列,那么最后一个元素总共会有 (n - k + 1) 个可能的选择。倒数第二个元素总共有 (n - k + 2) 个可能的选择,倒数第三个元素有 (n - k + 3) 个可能的选择,等等。因此,您可以使用 Lehmer代码并执行以下操作:
- 保持最后一位不变。
- 将倒数第二个元素乘以 (n - k + 1)。
- 将倒数第三个元素乘以 (n - k + 1)(n - k + 2)
4 ...
- 将第一个元素乘以 (n - k + 1)(n - k + 2)...(n - 1)
- 总结这些值。
这将为排列生成一个唯一的整数代码。
例如,我们的 Lehmer 代码是 (2, 0, 1),n = 7 和 k = 3。因此,我们将计算
1 + 0 × (7 - 3 + 1) + 2 × (7 - 3 + 2)(7 - 3 + 3)
= 1 + 2 × (5 × 6)
= 5 + 2 × 30
= 61
要反转此过程,您可以取整数并通过此过程向后运行它以恢复部分 Lehmer 代码。为此,首先将数字除以 (n - k + 1)(n - k + 2)...(n - 1) 以取回 Lehmer 代码的第一个数字。然后,将数字修改为 (n - k + 1)(n - k + 2)...(n - 1) 以去掉第一位。然后,将数字除以 (n - k + 1)(n - k + 2)...(n - 2) 得到 Lehmer 码的第二个数字,然后除以 (n - k + 1)( n - k + 2)...(n - 2) 去掉第二个数字。重复此操作,直到所有 Lehmer 码的数字都被重构。
例如,给定前缀 61、n = 7 和 k = 3,我们将从 61 除以 7 × 6 = 30 开始。这样得到 2,余数为 1。因此 Lehmer 码的第一个数字是 2 . 修改 30,我们得到数字 1。接下来,我们除以 6。这得到 0,余数为 1。因此第二个数字是 0。最后,我们读出剩余的数字,这给出了 Lehmer 的最后一个数字代码,1。我们已经恢复了我们的 Lehmer 代码(2, 0, 1),我们可以从中轻松地重构排列。
希望这会有所帮助!