C 给定词典索引的n-2置换(带重复)算法

C 给定词典索引的n-2置换(带重复)算法,c,algorithm,permutation,C,Algorithm,Permutation,我试图找到一种方法来确定n-2个数字的排列,根据一组n个数字的字典索引,允许重复。我们这样做的一个原因是在给定索引的情况下查找Prufer码。 考虑一组数为[1,2,3,4],我们将得到一组n-2置换为[1,1],[1,2],[1,3],[1,4]…[4,3],[4,4]。 我的问题是,在给定索引作为输入的情况下,是否有一种方法可以获得这样的排列,而不必枚举所有排列。我查看了此链接中的方法,但这可能会与n-2对象的排列有关。谢谢。这不是编程问题,更多的是理解问题。Prufer序列是一个序列或线性

我试图找到一种方法来确定n-2个数字的排列,根据一组n个数字的字典索引,允许重复。我们这样做的一个原因是在给定索引的情况下查找Prufer码。 考虑一组数为[1,2,3,4],我们将得到一组n-2置换为[1,1],[1,2],[1,3],[1,4]…[4,3],[4,4]。
我的问题是,在给定索引作为输入的情况下,是否有一种方法可以获得这样的排列,而不必枚举所有排列。我查看了此链接中的方法,但这可能会与n-2对象的排列有关。谢谢。

这不是编程问题,更多的是理解问题。Prufer序列是一个序列或线性应用程序,用于标记一组数字的每个可能排列,使每个标识唯一;因此,您可以将[a0,a1,a2,…,an-1]的Prufer序列定义为,例如

S = [a0,a1, ..., an-1], S in N

S -Prufer-> S x S

0 --------> [a0, a0]
1 --------> [a0, a1]
      ...
n-1 ------> [a0, an-1]
n --------> [a1, a0]
n+1 ------> [a1, a1]
      ...
2n-1 -----> [a1, an-1]
2n -------> [a2, a0]
2n+1 -----> [a2, a1]
等等。。。 然后,在一般情况下,您可以确定索引i为

p(i)=[a_sub(i/n),a_sub(i模n)]。


请注意,这个Prufer系列只是一个简单的例子:您可以定义自己的,记住它必须始终标识整个置换集,并使每个标识唯一(即,基础代数中的双活动线性应用)

这不是一个编程问题,更多的是关于理解。Prufer序列是一个序列或线性应用程序,用于标记一组数字的每个可能排列,使每个标识唯一;因此,您可以将[a0,a1,a2,…,an-1]的Prufer序列定义为,例如

S = [a0,a1, ..., an-1], S in N

S -Prufer-> S x S

0 --------> [a0, a0]
1 --------> [a0, a1]
      ...
n-1 ------> [a0, an-1]
n --------> [a1, a0]
n+1 ------> [a1, a1]
      ...
2n-1 -----> [a1, an-1]
2n -------> [a2, a0]
2n+1 -----> [a2, a1]
等等。。。 然后,在一般情况下,您可以确定索引i为

p(i)=[a_sub(i/n),a_sub(i模n)]。


请注意,这个Prufer系列只是一个简单的例子:您可以定义自己的置换集,记住它必须始终标识整个置换集,并使每个标识唯一(即,基础代数中的双活动线性应用程序)

可以通过将秩转换为基数n的数字,并将其数字解释为基于0的索引,来计算一组n个数字中具有给定秩的排列:

集合:[1,2,3,4]
基于0的排名:9
基4中的9:21
基于0的索引:[2,1]
排列:[3,2]

集合:[a、b、c、d、e]
基于0的排名:64
基5中的64:224
基于0的索引:[2,2,4]
排列:[c,c,e]

类似这样的东西应该可以做到,其中
set
是一个包含n个数字的int数组,
perm
是一个足够大的int数组,可以容纳n-2个数字:

void置换(int*set,int-n,int-rank,int*perm){
对于(int k=n-2;k>0;--k){
perm[k-1]=集合[rank%n];
秩/=n;
}
}

(以上代码假设输入有效)

可以通过将秩转换为基数n的数字,并将其数字解释为基于0的索引,来计算一组n个数字中具有给定秩的排列:

集合:[1,2,3,4]
基于0的排名:9
基4中的9:21
基于0的索引:[2,1]
排列:[3,2]

集合:[a、b、c、d、e]
基于0的排名:64
基5中的64:224
基于0的索引:[2,2,4]
排列:[c,c,e]

类似这样的东西应该可以做到,其中
set
是一个包含n个数字的int数组,
perm
是一个足够大的int数组,可以容纳n-2个数字:

void置换(int*set,int-n,int-rank,int*perm){
对于(int k=n-2;k>0;--k){
perm[k-1]=集合[rank%n];
秩/=n;
}
}

(以上代码假设输入有效)

以下是m69想法的一些JavaScript代码:

函数f(秩、arr){
var n=阵列长度,
res=新数组(n-2).fill(arr[0]),
i=n-3;
while(职级){
res[i--]=arr[rank%n];
等级=数学楼层(等级/n);
}
返回res;
}

log(f(64,['a','b','c','d','e'])以下是m69想法的一些JavaScript代码:

函数f(秩、arr){
var n=阵列长度,
res=新数组(n-2).fill(arr[0]),
i=n-3;
while(职级){
res[i--]=arr[rank%n];
等级=数学楼层(等级/n);
}
返回res;
}

log(f(64,['a','b','c','d','e'])…无论设置的大小n和序列长度k之间有什么连接,这都有效。索引空间增加到n^k,在OP的情况下正好是n^(n-2)…并且不管设置大小n和序列长度k之间有什么联系,这都是有效的。索引空间增加到n^k,在OP的情况下正好是n^(n-2);秩保持为零,因此您可以在那里进行填充(请参阅我在答案中添加的C代码);秩保持为零,因此您可以在那里进行填充(请参阅我在答案中添加的C代码)。