所有可能的话

时间:2011-03-31 17:41:30

标签: java algorithm logic

我想用a-z创建所有可能的5个字母的单词。请建议任何好的和快速的算法。

我尝试创建一个,它看起来像这样......

     byte[] allchar=new byte[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
 int lengthOfAllChar=allchar.length;
         System.out.println(lengthOfAllChar);
        for (int i = 0; i < lengthOfAllChar; i++){
            for(int j = 0; i < lengthOfAllChar; j++){
                StringBuffer finalWordBuffer = new StringBuffer();
                finalWordBuffer.append((char)allchar[i]);
                finalWordBuffer.append((char)allchar[j]);
            }
        }

4 个答案:

答案 0 :(得分:24)

以下是为任意长度的任何字符集生成所有序列的示例:

public class WordPermutations {
    public static void main(String[] args) {
        char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
        int len = 5;
        iterate(chars, len, new char[len], 0);
    }

    public static void iterate(char[] chars, int len, char[] build, int pos) {
        if (pos == len) {
            String word = new String(build);
            // do what you need with each word here
            return;
        }

        for (int i = 0; i < chars.length; i++) {
            build[pos] = chars[i];
            iterate(chars, len, build, pos + 1);
        }
    }
}

在我的机器上花费大约250ms来迭代所有11,881,376个序列。

请注意,新的char[len]仅在开头创建一次,并作为构建用于构建排列。第一次拨打iterate()的电话以pos 0开头。跳到for循环,循环遍历每个字符。构建的第一个char设置为,然后我们递归调用相同的方法在pos + 1设置下一个。一旦发生了5次,pos将在len。这是pos == len在方法顶部开始的时候。然后它只是根据构建中构建的String来构建,这就是你的话。

答案 1 :(得分:4)

这也可以在没有递归的情况下轻松完成(在C中)

int i, k, n;
char tmp[6]; tmp[5] = 0;
for (i=0;i<26*26*26*26*26;i++) {
   n = i;
   for (k=4;k>=0;k--){
      tmp[k] = 'a' + (n % 26); 
      n /= 26;
   }
   output_string(tmp);
}

或者你可以随身携带:

char tmp[6]; int i, k;
strcpy(tmp, "aaaaa");
for (i=0;i<26*26*26*26*26;i++) {
   output_string(tmp);
   tmp[4]++;
   k = 4;
   while (k > 0 && tmp[k] == 'z') { tmp[k] = 'a'; k--; tmp[k]++; }
}

答案 2 :(得分:2)

public static List<String> getAll(int length) {
    final char[] chars = "0123456789".toCharArray();
    final double NUMBER_OF_PERMUTATIONS = Math.pow(chars.length, length);

    List<String> words = new ArrayList<>(Double.valueOf(
            NUMBER_OF_PERMUTATIONS).intValue());

    char[] temp = new char[length];
    Arrays.fill(temp, '0');

    for (int i = 0; i < NUMBER_OF_PERMUTATIONS; i++) {
        int n = i;
        for (int k = 0; k < length; k++) {
            temp[k] = chars[n % chars.length];
            n /= chars.length;
        }
        words.add(String.valueOf(temp));
    }
    return words;
}  

以下是antti.huima代码的Java 7版本。

答案 3 :(得分:0)

这是一个让你尝试的算法,伪代码:

array seenWords;
while size of seenWords[] < 26^5:
  generate random string of length 5 letters
  is string in seenWords?
  yes:
    go back to while
  no:
    push string onto end of seenWords[]
done while

您应该能够轻松地将此伪代码转换为适当的Java代码。唯一棘手的一点是生成随机字符串。你可以拿出你的字母数组,选择1到26之间的随机值,然后用它来写一个字母。重复那五次,你有一个五个字母的字符串!

这是一个“好”还是“快”的算法取决于你。你还没有定义“好”或“快”的意思,所以我无法判断。您的标准可能与我不同。

请注意,这将生成所有包含五个字母的字符串。这些可能不是文字。从您的示例代码判断,您希望所有字符串中包含五个字母,而不是包含五个字母的字符。