Javascript 反向置换指数
我编写了一个函数,用于根据索引计算数组[a,b,c,…]的排列,例如:Javascript 反向置换指数,javascript,algorithm,combinatorics,discrete-mathematics,Javascript,Algorithm,Combinatorics,Discrete Mathematics,我编写了一个函数,用于根据索引计算数组[a,b,c,…]的排列,例如: 0 -> a b c 1 -> a c b 2 -> b a c 3 -> b c a 4 -> c a b 5 -> c b a 通过此递归函数: function factorial(n) { return n <= 1 ? 1 : n*factorial(n-1); } function permutation(ar, n) { if (ar.length
0 -> a b c
1 -> a c b
2 -> b a c
3 -> b c a
4 -> c a b
5 -> c b a
通过此递归函数:
function factorial(n) { return n <= 1 ? 1 : n*factorial(n-1); }
function permutation(ar, n) {
if (ar.length == 1) return [ar[0]];
var x = factorial(ar.length-1); // get first element
return ar.splice(Math.floor(n/x),1).concat( permutation( ar, n % x ) )
}
我可以计算所有排列,计算它们的倒数,并建立它的索引,但是似乎应该有一种数学方法来获得倒数排列的索引,而不需要计算它 我不知道是否有数学方法可以实现这一点,但您可以通过使用hashmap以更快的方式实现这一点
var dict = {};
dict['abc'] = 0;
dict['acb'] = 1;
dict['bac'] = 2;
dict['bca'] = 3;
dict['cab'] = 4;
dict['cba'] = 5;
所以,一旦你有了这个,你可以反转一个普通的字符串,并使用上面形成的hashmap获取它的索引值
希望这有帮助 我不知道是否有数学方法可以实现这一点,但您可以通过使用hashmap以更快的方式实现这一点
var dict = {};
dict['abc'] = 0;
dict['acb'] = 1;
dict['bac'] = 2;
dict['bca'] = 3;
dict['cab'] = 4;
dict['cba'] = 5;
所以,一旦你有了这个,你可以反转一个普通的字符串,并使用上面形成的hashmap获取它的索引值
希望这有帮助 如果你看一下你的排列,你会发现它的结构如下:(例如lenght=3) 首先,你的排列被分成3组,每组2个!元素 然后将这些子组分为2组,长度为1,在此之后,子组不再被划分 所以事实上,你的排列可以通过先声明它在哪个子组中,然后声明它在哪个子组中来“查找” 例如,排列2:“bac”位于子组1(从0开始)和子组0中 所以我们可以说2=(1,0),就像3=1*(2!)+0*(1!) 4将是(2,0) 现在如果我们翻转2,它是(0,1),再加上4,(2,0),我们会得到(2,1) 这对所有排列都是正确的 实质上: (n=排列的长度) 将索引写为*(n-1)!+b*(n-2)!+…+z*(1!)(a=楼层(指数/(n-1)),b=楼层(指数%(n-1))/(n-2)!,…) 找到一个数字,这样如果你翻转最小的一个,把它们加在一起,你就得到了(n-1,n-2,n-3,…,1)
可能有一种有效的算法可以做到这一点。如果你看一下你的排列,你会发现它的结构如下:(例如lenght=3) 首先,你的排列被分成3组,每组2个!元素 然后将这些子组分为2组,长度为1,在此之后,子组不再被划分 所以事实上,你的排列可以通过先声明它在哪个子组中,然后声明它在哪个子组中来“查找” 例如,排列2:“bac”位于子组1(从0开始)和子组0中 所以我们可以说2=(1,0),就像3=1*(2!)+0*(1!) 4将是(2,0) 现在如果我们翻转2,它是(0,1),再加上4,(2,0),我们会得到(2,1) 这对所有排列都是正确的 实质上: (n=排列的长度) 将索引写为*(n-1)!+b*(n-2)!+…+z*(1!)(a=楼层(指数/(n-1)),b=楼层(指数%(n-1))/(n-2)!,…) 找到一个数字,这样如果你翻转最小的一个,把它们加在一起,你就得到了(n-1,n-2,n-3,…,1)
可能有一种有效的算法可以做到这一点。我来晚了一点。。。这是可以计算出来的。您可以按原样使用此C代码:
using System;
using System.Collections.Generic;
namespace WpfPermutations
{
public class PermutationOuelletLexico3<T>
{
// ************************************************************************
private T[] _sortedValues;
private bool[] _valueUsed;
public readonly long MaxIndex; // long to support 20! or less
// ************************************************************************
public PermutationOuelletLexico3(T[] sortedValues)
{
if (sortedValues.Length <= 0)
{
throw new ArgumentException("sortedValues.Lenght should be greater than 0");
}
_sortedValues = sortedValues;
Result = new T[_sortedValues.Length];
_valueUsed = new bool[_sortedValues.Length];
MaxIndex = Factorial.GetFactorial(_sortedValues.Length);
}
// ************************************************************************
public T[] Result { get; private set; }
// ************************************************************************
/// <summary>
/// Return the permutation relative to the index received, according to
/// _sortedValues.
/// Sort Index is 0 based and should be less than MaxIndex. Otherwise you get an exception.
/// </summary>
/// <param name="sortIndex"></param>
/// <param name="result">Value is not used as inpu, only as output. Re-use buffer in order to save memory</param>
/// <returns></returns>
public void GetValuesForIndex(long sortIndex)
{
int size = _sortedValues.Length;
if (sortIndex < 0)
{
throw new ArgumentException("sortIndex should greater or equal to 0.");
}
if (sortIndex >= MaxIndex)
{
throw new ArgumentException("sortIndex should less than factorial(the lenght of items)");
}
for (int n = 0; n < _valueUsed.Length; n++)
{
_valueUsed[n] = false;
}
long factorielLower = MaxIndex;
for (int index = 0; index < size; index++)
{
long factorielBigger = factorielLower;
factorielLower = Factorial.GetFactorial(size - index - 1); // factorielBigger / inverseIndex;
int resultItemIndex = (int)(sortIndex % factorielBigger / factorielLower);
int correctedResultItemIndex = 0;
for(;;)
{
if (! _valueUsed[correctedResultItemIndex])
{
resultItemIndex--;
if (resultItemIndex < 0)
{
break;
}
}
correctedResultItemIndex++;
}
Result[index] = _sortedValues[correctedResultItemIndex];
_valueUsed[correctedResultItemIndex] = true;
}
}
// ************************************************************************
/// <summary>
/// Calc the index, relative to _sortedValues, of the permutation received
/// as argument. Returned index is 0 based.
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
public long GetIndexOfValues(T[] values)
{
int size = _sortedValues.Length;
long valuesIndex = 0;
List<T> valuesLeft = new List<T>(_sortedValues);
for (int index = 0; index < size; index++)
{
long indexFactorial = Factorial.GetFactorial(size - 1 - index);
T value = values[index];
int indexCorrected = valuesLeft.IndexOf(value);
valuesIndex = valuesIndex + (indexCorrected * indexFactorial);
valuesLeft.Remove(value);
}
return valuesIndex;
}
// ************************************************************************
}
}
使用系统;
使用System.Collections.Generic;
命名空间WpfPermutations
{
公共类置换
{
// ************************************************************************
私人T[]_分类值;
使用的私有布尔值【】;
public readonly long MaxIndex;//long支持20!或更少
// ************************************************************************
公共置换ouelletlexico3(T[]分类值)
{
if(sortedValues.Length=MaxIndex)
{
抛出新的ArgumentException(“sortIndex应该小于阶乘(项的长度)”;
}
用于(int n=0;n<_valueUsed.Length;n++)
{
_valueUsed[n]=假;
}
长阶乘低=最大索引;
对于(int index=0;index