我将在这个答案中涵盖您问题的一半 - “unranking”。目标是有效地找到有序字符串 [abcd...] 的字典第“K”个排列。
为此,我们需要了解阶乘数字系统(factoradics)。阶乘数字系统使用阶乘值而不是数字的幂(二进制系统使用 2 的幂,十进制使用 10 的幂)来表示位值(或基数)。
位置值(基础)是 -
5!= 120 4!= 24 3!=6 2!= 2 1!=1 0!=1 etc..
第 0 位的数字始终为 0。第一位的数字(底数 = 1!)可以是 0 或 1。第二位的数字(底数为 2!)可以是 0,1 或2 以此类推。一般来说,第n位的数字可以取0-n之间的任意值。
前几个数字表示为因子-
0 -> 0 = 0*0!
1 -> 10 = 1*1! + 0*0!
2 -> 100 = 1*2! + 0*1! + 0*0!
3 -> 110 = 1*2! + 1*1! + 0*0!
4 -> 200 = 2*2! + 0*1! + 0*0!
5 -> 210 = 2*2! + 1*1! + 0*0!
6 -> 1000 = 1*3! + 0*2! + 0*1! + 0*0!
7 -> 1010 = 1*3! + 0*2! + 1*1! + 0*0!
8 -> 1100 = 1*3! + 1*2! + 0*1! + 0*0!
9 -> 1110
10-> 1200
字符串的第 n 次字典排列与其因子表示之间存在直接关系。
例如,这里是字符串“abcd”的排列。
0 abcd 6 bacd 12 cabd 18 dabc
1 abdc 7 badc 13 cadb 19 dacb
2 acbd 8 bcad 14 cbad 20 dbac
3 acdb 9 bcda 15 cbda 21 dbca
4 adbc 10 bdac 16 cdab 22 dcab
5 adcb 11 bdca 17 cdba 23 dcba
如果仔细观察,我们可以在这里看到一个模式。第一个字母在每 6 次 (3!) 排列后发生变化。第二个字母在 2(2!) 排列后发生变化。第三个字母在每个 (1!) 排列后更改,第四个字母在每个 (0!) 排列后更改。我们可以利用这个关系直接找到第n个排列。
一旦我们用因子表示表示 n,我们就会考虑其中的每个数字,并将给定字符串中的一个字符添加到输出中。如果我们需要找到“abcd”的 14 次排列。 14 in factoradics -> 2100.
从第一个数字开始 -> 2,字符串是'abcd'。假设索引从 0 开始,从字符串中取出位置 2 的元素并将其添加到输出中。
Output String
c abd
2 012
下一个数字 -> 1.String 现在是“abd”。再次,在位置 1 处提取字符并将其添加到输出中。
Output String
cb ad
21 01
下一个数字 -> 0。字符串是“广告”。将位置 1 的字符添加到输出。
Output String
cba d
210 0
下一个数字 -> 0。字符串是“d”。将位置 0 处的字符添加到输出。
输出字符串
cbad''
2100
要将给定的数字转换为阶乘数字系统,请将该数字依次除以 1、2、3、4、5 等等,直到商变为零。每一步的提醒形成阶乘表示。
例如,将 349 转换为阶乘,
Quotient Reminder Factorial Representation
349/1 349 0 0
349/2 174 1 10
174/3 58 0 010
58/4 14 2 2010
14/5 2 4 42010
2/6 0 2 242010
349 的因数表示是 242010。