Algorithm 排列展开

Algorithm 排列展开,algorithm,language-agnostic,permutation,Algorithm,Language Agnostic,Permutation,我知道有一种算法(可以在网上找到)对排列进行排序,即给定一个排列,将整数索引返回到按字典顺序排序的排列列表中,但我不知道有任何unrank算法做相反的事情:给定一个索引I,按该字典顺序返回第I个排列 既然我找不到,谁能帮我解释一下吗?假设你正在排列字母(a、b、c) 有3×2×1=6个排列。其中,第三个字母以a开头,在词典中,第三个字母以b开头,在最后三个字母以c开头之前 这三分之一中的每一个都有两半,一个从选择第一个字母后留下的第一个字母开始,另一个从第二个字母开始 这两部分中的每一部分只有一

我知道有一种算法(可以在网上找到)对排列进行排序,即给定一个排列,将整数索引返回到按字典顺序排序的排列列表中,但我不知道有任何unrank算法做相反的事情:给定一个索引I,按该字典顺序返回第I个排列


既然我找不到,谁能帮我解释一下吗?

假设你正在排列字母(a、b、c)

有3×2×1=6个排列。其中,第三个字母以
a
开头,在词典中,第三个字母以
b
开头,在最后三个字母以
c
开头之前

这三分之一中的每一个都有两半,一个从选择第一个字母后留下的第一个字母开始,另一个从第二个字母开始

这两部分中的每一部分只有一个元素(最后一个字母)

因此,给定一组三个元素和一个介于0和5之间的索引(比如说
3
),我们可以(带提醒)除以每个“三分之一”的大小,得到第一个字母。现在:

  • 该集合的大小为n=3
  • 有n个=6排列
  • 有n=3组排列,从n个元素中的每一个元素开始
  • 每组有n号/n=(n-1)!=6/3=2个元素
为了确定第一个元素的索引,我们用2除以余数:

3÷2=1雷姆1

因为我们的集合是(a,b,c),这告诉我们第一个字母是
b

现在,我们可以从集合中删除字母b,并使用提醒作为新索引。我们得到集合(a,c)和索引1。重新应用算法

  • 该集合的大小为n=2
  • 有n个=2排列
  • 有n=2组排列,从n个元素中的每一个元素开始
  • 每组有n号/n=(n-1)!=2/2=1个元素
为了确定第一个元素的索引,我们用1除以余数:

1÷1=1 rem 0

因为我们的集合是(a,c),这告诉我们第一个第二个字母是
c

第三个集合被简化为singleton
a
,这是我们的第三个字母

指数为3的排列是b,c,a

让我们检查一下:

0 abc
1 acb
2 bac
3 bca <-- correct!
4 cab 
5 cba
0abc
1 acb
2 bac
3 bca(0)
{
var setSize=数学阶乘(set.Length-1);
var指数=n/setSize;
res.Concat(集合[索引]);
集合=索引>0?集合。子字符串(0,索引):“”+
索引
请参见查看“>此线程。这是您要查找的吗?这是另一个线程,带有图形。:)
public string NthPerm(string set, int n)
{
    var res = "";
    while (set.Length > 0)
    {
        var setSize = Math.Factorial(set.Length-1);
        var index = n/setSize;

        res.Concat(set[index]);

        set = index > 0 ? set.Substring(0, index) : "" +
              index < set.Length-1 ? set.Substring(index+1) : "";

        n = n % setSize;
    }
    return res;
}