我想找到大的k值从1到n的数字的第k个排列。 我发现了一个名为factoradic的方法,但我无法实现它。 任何其他方法也将是有用的。 有人可以帮忙吗?
答案 0 :(得分:1)
经过大量的白皮书和维基百科阅读后,我最终得到了这个(注意:排列是基于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();
}
}
答案 1 :(得分:0)
这是一篇带有C#实现的Microsoft文章:http://msdn.microsoft.com/en-us/magazine/cc163513.aspx
编辑:这是一个多汁位的粘贴(对于缺乏格式的道歉 - 这就是它在源文章中的表现)
public StringPerm(string[] atoms, int k)
{
this.element = new string[atoms.Length];
this.order = atoms.Length;
// Step #1 - Find factoradic of k
int[] factoradic = new int[this.order];
for (int j = 1; j <= this.order; ++j)
{
factoradic[this.order - j] = k % j;
k /= j;
}
// Step #2 - Convert factoradic[] to numeric permuatation in perm[]
int[] temp = new int[this.order];
int[] perm = new int[this.order];
for (int i = 0; i < this.order; ++i)
{
temp[i] = ++factoradic[i];
}
perm[this.order - 1] = 1;
// right-most value is set to 1.
for (int i = this.order - 2; i >= 0; --i)
{
perm[i] = temp[i];
for (int j = i + 1; j < this.order; ++j)
{
if (perm[j] >= perm[i])
++perm[j];
}
}
for (int i = 0; i < this.order; ++i) // put in 0-based form
--perm[i];
// Step #3 - map numeric permutation to string permutation
for (int i = 0; i < this.order; ++i)
this.element[i] = atoms[perm[i]];
}
答案 2 :(得分:0)
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();
}