Java 对应置换数

Java 对应置换数,java,arrays,sorting,permutation,Java,Arrays,Sorting,Permutation,我有一个给定的单词,对于它,我需要找到它对应的排序单词的排列数。 假设我有一个单词BABA,它对应的排序单词是,AABB,如果我开始排列这个排序单词,它将作为第二个“单词”出现在AABB,不管字母重复,然后是ABAB,ABBA,BABA。。所以单词BABA的排列数是5。 简单的方法是开始做所有可能的组合,然后与初始单词进行比较。 到目前为止,我已经做到了 import java.util.Arrays; public class Permutation { int location =1;

我有一个给定的单词,对于它,我需要找到它对应的排序单词的排列数。 假设我有一个单词BABA,它对应的排序单词是,AABB,如果我开始排列这个排序单词,它将作为第二个“单词”出现在AABB,不管字母重复,然后是ABAB,ABBA,BABA。。所以单词BABA的排列数是5。 简单的方法是开始做所有可能的组合,然后与初始单词进行比较。 到目前为止,我已经做到了

import java.util.Arrays;

public class Permutation {
 int location =1;
public static char[]  warray;

void printArray(char []a) {
 for (int i = 0; i < a.length; i++) {
 System.out.print(a[i]+" ");
 }
  System.out.println("location " + location );
}
 void permute(char []a,int k ) {
  if(k==a.length) {
     location++;
  // Check if the permuted word is the one looking for.
 if (Arrays.equals(a, warray))
  { System.out.println("final iteration k" + k);        
  printArray(a); 
  System.exit(0);}
  }
else
   for (int i = k; i < a.length; i++) {
   char temp=a[k];
   a[k]=a[i];
   a[i]=temp;
    permute(a,k+1);
   }
}

public static void main(String[] args) {
  if (args[0].length() > 25 )  {
     System.out.println(" Word not in permited range " );        
     System.exit(0);
 }
 else {
 Permutation p=new Permutation();
 warray = new char[args[0].length()];
  char [] wpermute = new char[args[0].length()];

for (int i = 0; i < args[0].length(); i++) {
     warray[i] = new Character(args[0].charAt(i));
     wpermute[i] = new Character(args[0].charAt(i));
 }

Arrays.sort(wpermute);

System.out.print("sorted word : " );
for (int i = 0; i < wpermute.length; i++) {
  System.out.print(wpermute[i]);
  }
  p.permute(wpermute,0);
  }
}
导入java.util.array;
公共类置换{
int位置=1;
公共静态字符[]warray;
void printary(char[]a){
for(int i=0;i25){
System.out.println(“单词不在许可范围内”);
系统出口(0);
}
否则{
置换p=新置换();
warray=new char[args[0].length();
char[]wpermute=new char[args[0].length();
对于(int i=0;i

但这可能是非常缓慢的性能。
我的第二个猜测是,像从未排序单词的第一个字母开始的二进制搜索一样,计算可能的排列,将这个字母作为排列的第一个字母,然后是第二个字母..所以…听起来好吗?

如果你只有两个字母,如果单词的长度是
N
和数字A的值为
n
,则排列的数目为
n选择n

如果有
N
字母总数和
N_a
N_b
,…,
N_z
描述每个字母的数量,则排列的总数为

N!/(n_a! n_b! n_c! ... n_z!)

签出,向下滚动到排列上的位。

另一个单词是疑问词,它的排序单词是EINOQSTU。 对于问题,q在位置1,在新词的位置5,需要做多少排列才能放入位置1=20161。 现在我看第二个字母,是U,在排序词的第8位,需要做多少排列,是24481

我想,我可以计算,而不是执行,把一个字母放在y位置,放在X位置所需要的数字排列,然后,所有的总和,就是整个单词所需要的排列


现在,如何计算这些数字,我知道必须是阶乘加上其他东西……不是吗?

所以我最终完成了代码,是的,需要检查多项式。 也从这里的相关帖子中得到了部分想法。 但这是我的密码

package WordPuzzle;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/** Rafael G.  */

public class WordPuzzle {

    static String sortWord (String[] wordinput){
        char [] wsorted = new char[wordinput[0].length()];
        wsorted = wordinput[0].toCharArray();
        Arrays.sort(wsorted);
        String aux="";
        for (int i = 0; i < wsorted.length; i++) {
            aux = aux + wsorted[i];
        }   
        return aux;
    }

    static void calculatePerm(String wordtofind,String wordsorted)
    {
        int sum = 0;
        int numberpermutations;
        char nextchar;
        int charlocremainder =0;
        String lowerLetters;
        String greaterLetters;

        Map<Character, Integer> characterCounts = new HashMap<Character, Integer> ();
        int count ;
        char letter;
        int factorial;
        int [] factorials = new int [wordsorted.length()+1];

        factorial =1;        
        numberpermutations = 1;
        int nMinusI;
        int nextcharcount;

        // set a mapping of repeated letters and its number 
        // and store factorial calculation.
        for (int i = 0; i < wordsorted.length(); i++) {
            letter = wordsorted.charAt(i);
            factorial = factorial * (i+1);
            factorials[i+1]= factorial;
            count = characterCounts.containsKey(letter) ? characterCounts.get(letter) + 1 : 1;
            characterCounts.put(letter, count);
           }

        String trimWord = new String(wordsorted);

        for (int i = 0; i < wordtofind.length() ; i++){
            nMinusI = wordtofind.length()-(i+1);
            nextchar = wordtofind.charAt(i);
            charlocremainder = trimWord.indexOf(nextchar);
            lowerLetters = trimWord.substring(0, charlocremainder); 

            // Calculate the denominator  which is the number of repeated letters
            // of the formula (N-i)! * (Na+Nb) /Na!Nb!.. 
              nextcharcount = characterCounts.get(nextchar);
              characterCounts.put(nextchar, nextcharcount-1);
              int denomfact = factorials[nextcharcount];
              if (lowerLetters.length() > 1){
                   char x = lowerLetters.charAt(0);
                   char y = x;
                  for (int k = 1 ; k < lowerLetters.length(); k++){
                      y = lowerLetters.charAt(k);
                      if (x != y) {
                          denomfact = denomfact * factorials[characterCounts.get(x)];
                          x = y;
                      }
                     }
                     denomfact = denomfact * factorials[characterCounts.get(y)];
                   }

            numberpermutations = factorials[nMinusI] * lowerLetters.length() / denomfact;
            sum = sum + numberpermutations;
            greaterLetters= trimWord.substring(charlocremainder+1);         
            trimWord = lowerLetters.concat(greaterLetters);

        }
           System.out.println(" Rank of permutation " + (sum+1));
    }

    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) {
        long startTime = System.nanoTime();
        String wordsorted;
        String wordentered;

        if (args[0].length() > 25 )  {
            System.out.println("Word not in permited range " );        
            System.exit(0);
        }
        else {
            wordentered = args[0].toUpperCase();
            wordsorted = sortWord(args).toUpperCase();
            calculatePerm(wordentered,wordsorted);
        }

        long endTime = System.nanoTime();
        System.out.println("Took "+(endTime - startTime)/1000000000.0 + " seconds");
        System.out.println("Took "+(endTime - startTime)* 0.000001 + " milliseconds");
    }

 }
packagewordpuzzle;
导入java.util.array;
导入java.util.HashMap;
导入java.util.Map;
/**拉斐尔G*/
公共类字谜{
静态字符串sortWord(字符串[]wordinput){
char[]wsorted=new char[wordinput[0].length();
wsorted=wordinput[0]。toCharArray();
Arrays.sort(wsorted);
字符串aux=“”;
for(int i=0;i1){
char x=Lowerleters.charAt(0);
chary=x;
对于(int k=1;k