Java生成String的所有可能排列

时间:2012-12-22 18:59:36

标签: java string permutation

我知道这个问题已被多次询问,但我正在寻找一种非常快速的算法来生成长度为8的字符串的所有排列。我试图生成一个长度为8的字符串,其中字符串中的每个字符可以是任何字符0-9或az(总共36个选项)。目前,这是我必须执行的代码:

for(idx[2] = 0; idx[2] < ch1.length; idx[2]++)
for(idx[3] = 0; idx[3] < ch1.length; idx[3]++)
    for(idx[4] = 0; idx[4] < ch1.length; idx[4]++)
        for(idx[5] = 0; idx[5] < ch1.length; idx[5]++)
            for(idx[6] = 0; idx[6] < ch1.length; idx[6]++)
                for(idx[7] = 0; idx[7] < ch1.length; idx[7]++)
                    for(idx[8] = 0; idx[8] < ch1.length; idx[8]++)
                        for(idx[9] = 0; idx[9] < ch1.length; idx[9]++) 
                            String name = String.format("%c%c%c%c%c%c%c%c%c%c",ch1[idx[0]],ch2[idx[1]],ch3[idx[2]],ch4[idx[3]],ch5[idx[4]],ch6[idx[5]],ch7[idx[6]],ch8[idx[7]],ch9[idx[8]],ch10[idx[9]]);

正如您所看到的,这段代码无论如何都不是很漂亮。此外,此代码每秒可生成280,000个字符串。我正在寻找一种比这更快的算法。

我尝试了一种递归方法,但这似乎比这种方法运行得慢。建议?

2 个答案:

答案 0 :(得分:10)

应该更快(每秒产生超过百万次输出的方式),至少它读起来更加愉快:

final long count = 36L * 36L * 36L * 36L * 36L * 36L * 36L * 36L;

for (long i = 0; i < count; ++i) {
    String name = StringUtils.leftPad(Long.toString(i, 36), 8, '0');
}

这会利用你的问题:

  

生成一个长度为8的字符串,其中字符串中的每个字符可以是0-9或a-z中的任意字符(总共36个选项)

可以改写为:

打印基础-36系统

0的所有数字,直到36^8

很少注意到:

  • 输出按定义排序,很好!

  • 我使用StringUtils.leftPad()来简化,另请参阅:How can I pad an integers with zeros on the left?

  • 您正在寻找的不是permutation

  • 通过利用您生成所有后续数字的事实,您可以进一步轻松改进此算法:

    final int MAX = 36;
    final long count = 1L * MAX * MAX * MAX * MAX * MAX * MAX * MAX * MAX * MAX * MAX;
    
    final char[] alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
    final int[] digits = new int[8];
    final char[] output = "00000000".toCharArray();
    
    for (long i = 0; i < count; ++i) {
        final String name = String.valueOf(output);
    
        // "increment"
        for (int d = 7; d >= 0; --d) {
            digits[d] = (digits[d] + 1) % MAX;
            output[d] = alphabet[digits[d]];
            if (digits[d] > 0) {
                break;
            }
        }
    
    }
    

上面的程序,在我的计算机上,每秒生成超过 3000万个字符串。而且还有很大的改进空间。

答案 1 :(得分:0)

这段代码可能看起来更漂亮 - 或者至少更复杂;)

boolean incrementIndex( int[] idx, final int maxValue ) {
  int i = 0;
  int currIndexValue;
  do {
    currIndexValue = idx[i];
    currIndexValue++;
    if ( currIndexValue > maxValue ) {
      currIndexValue = 0;
    }
    idx[i] = currIndexValue;
    i++;
  } while ( currIndexValue == 0 && i < idx.length );

  return i < idx.length;
}



do {
  // create String from idx[0]...idx[8]
} while ( incrementIndex(idx, 35) );