Algorithm 使用factoradic的第k置换
对于k的大值,我想找到从1到n的第k个数字排列。 我发现了一个名为factoradic的数字方法,但我无法实现它。 任何其他方法也将是有用的。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
有人能帮忙吗?这是一篇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();
}