2012-10-31 125 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