2012-10-31 145 views
8

網站上有一些類似的問題有一些幫助,但我無法完全確定這個問題,所以我希望這不是重複的。在Java中使用重複排列數組,重複使用

這是一個家庭作業,你有一組字符集[A,B,C],並且必須使用遞歸來獲得所有的排列(帶重複)。我有排序的代碼做這個:

char[] c = {'A', 'B' , 'C'}; 

public void printAll(char[] c, int n, int k) { 
    if (k == n) { 
     System.out.print(c); 
     return; 
    } 
    else { 
     for (int j = 0; j<n; j++) { 
     for (int m = 0; m<n; m++) { 
      System.out.print(c[k]); 
      System.out.print(c[j]); 
      System.out.print(c[m] + "\r\n"); 
     } 
     } 
    }   
    printAll(c, n, k+1);  
} 

然而,參數n應定義輸出的長度,因此這個功能打印出長度爲3的所有排列,它不能做他們長2.我的嘗試了我所能想到的一切,並對Google的搜索結果感到厭倦,而且我自己也因爲無法解決似乎是一個相當簡單的問題而感到惱火。

+0

什麼是 「有重複」 的意思是在這裏嗎? – seh

+0

這只是意味着一旦使用了一個字符,它就可以再次使用。所以可能的輸出數是3^3,而不是3 !. – user1788424

回答

6

如果我理解正確,您會得到一組字符c和所需長度n

從技術上講,不存在重複排列的情況。我假設你想要所有長度爲n的字符串和來自c的字母。

你可以這樣來做:

to generate all strings of length N with letters from C 
-generate all strings of length N with letters from C 
    that start with the empty string. 

to generate all strings of length N with letters from C 
    that start with a string S 
-if the length of S is N 
    -print S 
-else for each c in C 
    -generate all strings of length N with letters from C that start with S+c 

在代碼:

printAll(char[] c, int n, String start){ 
    if(start.length >= n){ 
    System.out.println(start) 
    }else{ 
    for(char x in c){ // not a valid syntax in Java 
     printAll(c, n, start+x); 
    } 
    } 
} 
+0

您,先生,您不僅僅是一位紳士和學者。你是一位王子,一位紳士,一位學者。網上有些人提出了類似的建議,除了使用數組而不是字符串。但是,你的解釋更清晰。 – user1788424

+0

作爲參考,如果有人有興趣,這裏是最後的函數,其中n參數控制每行打印的長度: public void printAll3(char [] c,int n,int k,String s) (s.length()> = n) { if(s.length()> = n) {System.out.print(s +「\ r \ n」); (k,n,k + 1,s + c [i]);其中if(k user1788424

+0

@JanDvorak我知道這是舊的,但我有一個類似的問題,我試圖解決,我修改了這一點,它完全working.Wowever但我不明白你最終調用printAll(c,n,開始+ x)的作品。我打印出來,並開始像這樣的頭幾個電話(a,aa,aaa,aab,aac,ab,aba)。我不明白爲什麼它最終不會成爲(abc,abcabc,abcabcabc)。我希望你能解釋它。我一直在試圖追蹤它,並且我知道每次在循環內打印所有調用時,它會自動調用n次。無論如何,如果你能我想要更多的解釋。 – MichelleJS

1

我剛剛有一個想法。如果你添加了一個隱藏的字符(隱藏的H)[A,B,C,H],然後做了所有固定長度的排列(你說你知道該怎麼做)。然後當你讀完它時,你停在隱藏的角色上,例如[B,A,H,C]會變成(B,A)。

嗯,壞處是你必須跟蹤您創建哪些雖然[B,H,A,C]是一樣的[B,H,C,A]

+0

如果我正確地理解了這個問題,給出了所需的排列長度 –

1

這裏是C#版本生成指定的字符串與重複的排列:

(基本思想是 - 重複長度爲'n'的字符串的排列數是n^n)。

string[] GetPermutationsWithRepetition(string s) 
     { 
      s.ThrowIfNullOrWhiteSpace("s"); 
      List<string> permutations = new List<string>(); 
      this.GetPermutationsWithRepetitionRecursive(s, "", 
       permutations); 
      return permutations.ToArray(); 
     } 
     void GetPermutationsWithRepetitionRecursive(string s, string permutation, List<string> permutations) 
     { 
      if(permutation.Length == s.Length) 
      { 
       permutations.Add(permutation); 
       return; 
      } 
      for(int i =0;i<s.Length;i++) 
      { 
       this.GetPermutationsWithRepetitionRecursive(s, permutation + s[i], permutations); 
      } 
     } 

下面是相應的單元測試:

[TestMethod] 
     public void PermutationsWithRepetitionTests() 
     { 
      string s = ""; 
      int[] output = { 1, 4, 27, 256, 3125 }; 
      for(int i = 1; i<=5;i++) 
      { 
       s += i; 
       var p = this.GetPermutationsWithRepetition(s); 
       Assert.AreEqual(output[i - 1], p.Length); 
      } 
     } 
2

我用這個java的排列實現與重複。 A〜(n,m):n =陣列長度,m = k。 m可以大於或小於n。

public class Permutations { 


    static void permute(Object[] a, int k, PermuteCallback callback) { 
     int n = a.length; 

     int[] indexes = new int[k]; 
     int total = (int) Math.pow(n, k); 

     Object[] snapshot = new Object[k]; 
     while (total-- > 0) { 
      for (int i = 0; i < k; i++){ 
       snapshot[i] = a[indexes[i]]; 
      } 
      callback.handle(snapshot); 

      for (int i = 0; i < k; i++) { 
       if (indexes[i] >= n - 1) { 
        indexes[i] = 0; 
       } else { 
        indexes[i]++; 
        break; 
       } 
      } 
     } 
    } 

    public static interface PermuteCallback{ 
     public void handle(Object[] snapshot); 
    }; 

    public static void main(String[] args) { 
     Object[] chars = { 'a', 'b', 'c', 'd' }; 
     PermuteCallback callback = new PermuteCallback() { 

      @Override 
      public void handle(Object[] snapshot) { 
       for(int i = 0; i < snapshot.length; i ++){ 
        System.out.print(snapshot[i]); 
       } 
       System.out.println(); 
      } 
     }; 
     permute(chars, 8, callback); 
    } 

} 

示例輸出

aaaaaaaa 
baaaaaaa 
caaaaaaa 
daaaaaaa 
abaaaaaa 
bbaaaaaa 
... 
bcdddddd 
ccdddddd 
dcdddddd 
addddddd 
bddddddd 
cddddddd 
dddddddd