如何在Java中组合字符组成单词?

时间:2017-02-15 17:44:57

标签: java string algorithm

我需要长度为n的各种单词,并且在每个位置/索引处可以有不同的元素。

例如n = 5

对于第一个位置,允许的元素是:H,Y,U,B,N

对于第二个位置,允许的元素是:E,S,D

对于第三个位置,允许的元素是:L,O,P

对于第四个位置,允许的元素是:L,O,P

对于第五个位置,允许的元素是:O,K,L

所以可以形成的各种词语是:HELLO,YELLK,BDPOK等。

在Java中以一种有效的方式找出所有可能的单词的有效方法是什么?

3 个答案:

答案 0 :(得分:2)

我认为从每个字符串中递归选择每个字符,并且移动到下一个字符串是最简单的方法,我实现了java代码,我添加了一些注释,如果有什么不清楚请不要犹豫。

    static String s[] = {"HYUBN", "ESD", "LOP", "LOP", "OKL"};
    static ArrayList<String> comb; // arraylist is going to hold results.

    static void dfs(String x,int i) {
        if(i == s.length) {   // there is no more string that can be generated
            comb.add(x); // save the found string
            return;
        }
        for(int j=0;j<s[i].length();j++)  // for each character in the current string
            dfs(x+s[i].charAt(j),i+1); // take the current character and move to the next string
    }

    public static void main(String[] args) {
        comb = new ArrayList<>();
        dfs("",0);
        for(String x:comb) out.print(x + " ");
    }

答案 1 :(得分:1)

找到所有可能单词的最有效方法是获取统计数据和概率类,并探索如何计算组合和排列。您提出的示例中有5 * 3 * 3 * 3 * 3组合。

是的,Java将是一种有效的方法,可以为您的问题提供所有组合,但其他语言也可以。您也可以使用纸和笔来完成它,但您可能需要一台计算机,具体取决于您需要处理的组合数量。

祝你好运,社区期待看到你提出的示例代码。

答案 2 :(得分:1)

效率在很大程度上取决于可能的单词词典的组织方式。如果按字母顺序组织(在Java数组或 ArrayList 中),则在构建(从左到右)时检查有效组合将排除大量检查。例如,检查“ND ...”并找不到以它开头的单词将通过而不是检查NDLLO,NDLLK,NDLLL,NDLOO ...来节省时间......

Java TreeMap 可以是增量搜索的更好的数据结构,但如果单词源是有序的,我们只是添加,可能需要更长的时间来构造和更多的内存而不是简单的有序数组它们来自包含所有单词的文件中的数组。

对有序ArrayList的TreeMap和二进制搜索,每个都需要O(log n)时间,并且一旦初始字母与可能的字母不匹配就可以排除单词。包含“NDA”等缩写的非常彻底的字典会检查更多,较小的字典每2个字母组合可能只需要1或2个检查(注意,单个字母总是开始单词,因此无法检查单个字母)。

进一步细化可能是对单词集中每个单词的初始几个(或更多)字母进行散列(例如,使用Java HashMap ),以便在初始启动时进行O(n)查找,交易记忆更快。如果我们散布所有增量可能性(HE,HEL,HELL,HELLO,YE,YEL,......这是一个很大的内存成本),那么每次增量检查都是O(n),其中n是所需的增量检查次数。排除单词。

更多细化:如果我们控制单词集的组织,我们可以使用素数的模数按不同的字母顺序排序:

"HELLO" rearranged by mod 7, for example would be:  "HLOEL"

这可以提供更好的性能,因为它消除了在公共前缀周围的语言中自然发生的一些聚类。较高的素数会给出更好(更平坦)的分布。将它与前n次查找的哈希相结合,我们的性能会在O(n)和O(log n)之间变化。