Algorithm 使用factoradic的第k置换

Algorithm 使用factoradic的第k置换,algorithm,functional-programming,permutation,Algorithm,Functional Programming,Permutation,对于k的大值,我想找到从1到n的第k个数字排列。 我发现了一个名为factoradic的数字方法,但我无法实现它。 任何其他方法也将是有用的。 有人能帮忙吗?这是一篇Microsoft文章,其中介绍了C#实现: 编辑:这里是一个有趣的粘贴(为缺少格式表示歉意-这就是源文章中的内容) publicstringperm(字符串[]原子,整数k) { this.element=新字符串[atoms.Length]; this.order=atoms.Length; //步骤#1-找到k的factora

对于k的大值,我想找到从1到n的第k个数字排列。 我发现了一个名为factoradic的数字方法,但我无法实现它。 任何其他方法也将是有用的。
有人能帮忙吗?

这是一篇Microsoft文章,其中介绍了C#实现:

编辑:这里是一个有趣的粘贴(为缺少格式表示歉意-这就是源文章中的内容)

publicstringperm(字符串[]原子,整数k)
{
this.element=新字符串[atoms.Length];
this.order=atoms.Length;
//步骤#1-找到k的factoradic
int[]factoradic=new int[this.order];
对于(int j=1;j=0;--i)
{
perm[i]=温度[i];
对于(int j=i+1;j=perm[i])
++perm[j];
}
} 
for(int i=0;i
在阅读了大量白皮书和维基百科之后,我最终得出了这样的结论(注意:排列是基于0而不是基于1的)

测试代码

    [Test]
    public void Permutation_0_Returns_0123456789()
    {
        int[] factoradic = 0.ToFactoradic(10);
        int[] permutation = factoradic.ToPermutation(10);
        int[] expected = { 0,1,2,3,4,5,6,7,8,9 };
        Assert.AreEqual(expected, permutation);
    }
    [Test]
    public void Permutation_1_Returns_0123456798()
    {
        int[] factoradic = 1.ToFactoradic(10);
        int[] permutation = factoradic.ToPermutation(10);
        int[] expected = { 0, 1, 2, 3, 4, 5, 6, 7, 9, 8 };
        Assert.AreEqual(expected, permutation);
    }
实施

public static class IntExtensions
{
    //http://en.wikipedia.org/wiki/Factorial_number_system
    public static int[] ToFactoradic(this int value, int digitCount)
    {
        var factoradic = new int[digitCount];
        //Repeatedly divide by an increasing number
        //The reverse of the remainders forms the factoradic
        for (var i = 1; i <= digitCount; i++)
        {
            factoradic[digitCount - i] = value % i;
            value /= i;
        }
        return factoradic;
    }

    public static int[] ToPermutation(this int[] value, int digitCount)
    {
        //Initialise the digit list
        var digitList = new List<int>(digitCount);
        for (int i = 0; i < digitCount; i++)
        {
            digitList.Add(i);
        }
        //Loop through the factoradic pulling out each value in turn
        // Use this value as an index into the digit list removing each digit as it's used
        var permutationList = new List<int>(digitCount);
        for (var i = 0; i < value.Length; i++)
        {
            int indexIntoDigitList = value[i];
            int atom = digitList[indexIntoDigitList];
            digitList.RemoveAt(indexIntoDigitList);
            permutationList.Add(atom);
        }

        return permutationList.ToArray();
    }
}
公共静态类扩展
{
//http://en.wikipedia.org/wiki/Factorial_number_system
公共静态int[]ToFactoradic(此int值,int-digitCount)
{
var factoradic=新整数[digitCount];
//被越来越多的数字反复除以
//余数的倒数构成了factoradic
对于(var i=1;i
私有静态字符串nextPermutationSequence(int N,int k){
int nMinusOneFactorial=1;
列表=新的ArrayList();
StringBuilder buf=新的StringBuilder();
对于(int i=1;i=1;i--){
int位置=k/nMinusOneFactorial;
int val=list.get(位置);
buf.append(Integer.valueOf(val));
列表。删除(位置);
k=k%n最小系数;
nMinusOneFactorial=nMinusOneFactorial/i;
}
追加(Integer.valueOf(list.get(0));
返回buf.toString();
}

你想用哪种编程语言?我想用C语言,虽然这在理论上可以回答这个问题,但在这里包括答案的基本部分,并提供链接供参考。MSDN杂志文章链接有(毫不奇怪)已移动。注意,这篇文章发表在2004年7月号上,MSDN杂志的主要链接是:。可以从以下链接下载这篇文章:。这篇文章称为“测试运行”。
public static class IntExtensions
{
    //http://en.wikipedia.org/wiki/Factorial_number_system
    public static int[] ToFactoradic(this int value, int digitCount)
    {
        var factoradic = new int[digitCount];
        //Repeatedly divide by an increasing number
        //The reverse of the remainders forms the factoradic
        for (var i = 1; i <= digitCount; i++)
        {
            factoradic[digitCount - i] = value % i;
            value /= i;
        }
        return factoradic;
    }

    public static int[] ToPermutation(this int[] value, int digitCount)
    {
        //Initialise the digit list
        var digitList = new List<int>(digitCount);
        for (int i = 0; i < digitCount; i++)
        {
            digitList.Add(i);
        }
        //Loop through the factoradic pulling out each value in turn
        // Use this value as an index into the digit list removing each digit as it's used
        var permutationList = new List<int>(digitCount);
        for (var i = 0; i < value.Length; i++)
        {
            int indexIntoDigitList = value[i];
            int atom = digitList[indexIntoDigitList];
            digitList.RemoveAt(indexIntoDigitList);
            permutationList.Add(atom);
        }

        return permutationList.ToArray();
    }
}
private static String nextPermutationSequence(int N, int k){

        int nMinusOneFactorial = 1;
        List<Integer> list = new ArrayList<Integer>();
        StringBuilder buf = new StringBuilder();

        for(int i=1;i<=N;i++){
            list.add(i);
            nMinusOneFactorial*=i;
        }

        k=k-1;
        nMinusOneFactorial=nMinusOneFactorial/N;

        for(int i=N-1;i>=1;i--){

            int position = k/nMinusOneFactorial;
            int val = list.get(position);
            buf.append(Integer.valueOf(val));
            list.remove(position);
            k = k%nMinusOneFactorial;
            nMinusOneFactorial=nMinusOneFactorial/i;

        }

        buf.append(Integer.valueOf(list.get(0)));
        return buf.toString();
    }