有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java生成字符串的所有可能排列

我知道这个问题已经被问过很多次了,但我正在寻找一个非常快速的算法来生成长度为8的字符串的所有排列。我试图生成一个长度为8的字符串,其中字符串中的每个字符可以是0-9或a-z(总共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]]);

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

我尝试过一种递归方法,但它的运行速度似乎比这种方法慢。建议


共 (2) 个答案

  1. # 1 楼答案

    应该更快(每秒产生超过百万次输出),至少阅读起来肯定更愉快:

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

    这充分利用了您的问题:

    generate a String of length 8, where each character in the String can be any of the characters 0-9 or a-z (36 total options)

    可以重新表述为:

    在base-36系统中打印从036^8的所有数字

    几点注意:

    • 输出按定义排序,很好

    • 为了简单起见,我使用了^{},另请参见: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万个字符串。还有很大的改进空间

  2. # 2 楼答案

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

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