相应的排列数

时间:2014-03-07 01:35:20

标签: java arrays sorting permutation

我有一个给定的单词,因为我需要在相应的排序单词上找到它的排列数。 假设我有单词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);
  }
}

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

3 个答案:

答案 0 :(得分:2)

如果您只有2个字母,并且该字词的长度为N且A的数字为n,那么排列的数量为N choose n

如果您总共有N个字母,n_an_b,...,n_z描述了每个字母的数量,那么排列的总数是

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

查看Multinomials,向下滚动到排列位。

答案 1 :(得分:0)

另一个词是QUESTION,它的排序单词是EINOQSTU。 对于问题,q在位置1,在新单词的位置5中,需要做多少排列在位置1 = 20161。 现在我接受第二个问题,是U,在排序单词的第8位,需要做多少排列,是24481

我想,我可以计算,而不是执行将字母放在y位置所需的数字排列,处于X位置。然后,所有的总和,将是该单词所需的排列。

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

答案 2 :(得分:0)

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

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");
    }

 }