【问题标题】:All possible words所有可能的词
【发布时间】:2011-07-27 02:47:29
【问题描述】:

我想使用 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]);
            }
        }

【问题讨论】:

  • 我们说的是 1200 万字。祝你好运,快速算法:)
  • 大 O 表示法是 (O^5),在您的情况下 = 11881376 个字。祝你好运!
  • 一些上下文可能会有所帮助。什么语言(不是编程语言!)?为什么要生成它们,而不是从字典中查找它们?这是家庭作业,还是某种形式的作业?
  • @AutoMeta:编辑您的问题并在此处添加代码,而不是作为评论发布。不要忘记将其标记为代码。
  • -1 位选民,请解释一下这个问题有什么问题,我觉得这是一个完全正确的问题,我们不是来解决愚蠢的语法错误的。

标签: java algorithm logic


【解决方案1】:

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

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

这在我的机器上大约需要 250 毫秒来遍历所有 11,881,376 个序列。

请注意,新的char[len] 仅在开始时创建一次,并作为构建重复使用以构建排列。对iterate() 的第一次调用以pos0 开头。跳到 for 循环,它循环遍历每个字符。 build 的第一个字符设置为该字符,然后我们递归调用相同的方法将下一个字符设置为pos + 1。一旦这种情况发生 5 次,pos 将位于 len。这是pos == len 在方法顶部启动的时候。然后它只是从 build 中构建的内容构建 String,这就是你的话。

【讨论】:

  • 太酷了!!!!这似乎有点棘手...你能解释一下它是如何工作的......这真的很有帮助。
  • 当然,我会解释的。请注意,new char[len] 在开始时仅创建一次,并作为build 重复使用以构建排列。对iterate() 的第一次调用以pos 为0 开始。跳到for 循环,它循环遍历每个charsbuild 的第一个 char 设置为该值,然后我们递归调用相同的方法将下一个设置为 pos + 1。一旦这种情况发生 5 次,pos 将位于len。这是pos == len 在方法顶部启动的时候。然后它只是从build 中构建的内容构建一个String,这就是你的话。
  • 只是更正......它们不是排列,而只是长度为 5 的序列。当你有 26 个字符时,一个 5 字母的单词不能是它们的“排列”。
  • 我喜欢您使用名为“迭代”的方法进行递归... ;)
  • @antti:哎呀,你是对的,将排列重命名为序列。
【解决方案2】:

这也可以很容易地完成,无需递归(在 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]++; }
}

【讨论】:

    【解决方案3】:
    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 版本代码。

    【讨论】:

    • 不错。奇迹般有效。谢谢。
    【解决方案4】:

    这是一个供您试用的算法,采用伪代码:

    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 之间的随机值,然后将它用于一个字母。重复五次,你就有了一个五个字母的字符串!

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

    请注意,这将生成所有包含五个字母的字符串。这些可能不会是文字。从您的示例代码来看,您需要所有包含五个字母的字符串,而不是包含五个字母的单词。

    【讨论】:

    • 为什么要让生成随机数变得复杂?五个嵌套的for 循环保证创建所有“单词”,没有重复。
    • 是seenWords 中的字符串吗?这变得很困难......你必须匹配每个生成的单词......
    • @vlad:“这是一个‘好’还是‘快’的算法取决于你。” :-) 解决这个问题的方法很明显,我给出了一个不明显的方法。
    【解决方案5】:
    public void wordCreator(int length){
        Random rnd=new Random();
        String word;
        do{
            word="";
            for(int j=0; j<length; j++){
                int index=rnd.nextInt(data.length);   //data is a String array letter of the alpabet
                word+=data[index];
            }
        }while(wordMap.containsValue(word));
        wordMap.put(i, word);
        i++;
    

    }

    这是你的算法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 2013-04-24
      • 2015-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      相关资源
      最近更新 更多