【问题标题】:How to create words of random letters?如何创建随机字母的单词?
【发布时间】:2014-03-20 13:16:15
【问题描述】:

这是我的任务说明:

“构建一个程序,让用户根据随机字母结果创建不同的单词。 必须根据字典检查单词。”

这是目前为止的代码:

import java.util.Arrays;



public class AngloTrainer {
// ...

public AngloTrainer(String dictionaryFile) throws IOException {
    // load dictionary?
    //what else?
}

private String sort(String s){

    //Sort the letters in a string. 
    char[] tecken = s.toCharArray();
    String sorted = Arrays.sort(tecken);
    return sorted;

}

// use this to verify loadDictionary
private void dumpDict() {
    // Print out the dictionary at the screen.
      // ... define!
}

private void loadDictionary( String fileName ) {
    // Read the dictionary into a suitable container.
    // The file is a simple text file. One word per line.
    FileReader flr = new Filereader(fileName);  
    BufferedReader bfr = new BufferedReader(flr);
    String line;
    //collection/treeset?? maybe other??
    while((line = bfr.readLine()) !=null ){
        //save to a collention, but which?
    }
}

private String randomLetters( int length ) {
    // this makes vovels a little more likely
    String letters = "aabcdeefghiijklmnoopqrstuuvwxyyz";  
    StringBuffer buf = new StringBuffer(length);
    for ( int i = 0; i < length; i++ ) 
        buf.append( letters.charAt(randomGenerator.nextInt(letters.length())));

    return buf.toString();
}


/* Def. includes    
 * Let #(x,s) = the number of occurrences of the charcter x in the string s.
 * includes(a,b) holds iff for every character x in b, #(x,b) <= #(x,a)
 * 
 * A neccessary precondition for includes is that both strings are sorted
 * in ascending order.
 */
private boolean includes( String a, String b ) {
    if ( b == null || b.length() == 0 )
        return true;
    else if ( a == null || a.length() == 0 )
        return false;

    //precondition: a.length() > 0 && b.length() > 0
    int i = 0, j = 0;
    while ( j < b.length() ) {
        if (i >= a.length() || b.charAt(j) < a.charAt(i))
            return false;
        else if (b.charAt(j) == a.charAt(i)) {
            i++; j++;
        } else if (b.charAt(j) > a.charAt(i))
            i++;
    }
    //postcondition: j == b.length()
    return true;
}




public static void main(String[] args) {
    // ... define!
}
}

我应该为 loadDictionary 方法使用哪个集合? 正如作业所说,我需要根据字典集合检查我输入的单词。

【问题讨论】:

  • 我建议你构建一个查找效率高的 trie!
  • 你尝试过哪些收藏?当你尝试它们时发生了什么?
  • 您已标记问题hashsettreeset。您是否尝试过其中任何一种?

标签: java algorithm sorting hashset treeset


【解决方案1】:

HashSet 提供更好的平均案例理论复杂度 - 但是请注意,HashSet 根据定义是无序的。这意味着“真实”词之间没有相关性(例如,catcatfish 可以放置得很远)。
Hashset 提供O(1)(或O(|S|),因为您确实需要读取字符串)查找和插入。

理论上,TreeSetHashSet 慢,并且具有 O(logN)(或者再次,O(|S|logn),因为仍然需要读取字符串)。
但是,TreeSetSortedSet 的一个实例。这意味着根据使用的比较器,彼此“接近”的单词也将被放置在其中。在String.compareTo() 的默认实现中 - 使用的顺序是lexicographic order。这意味着共享相同前缀的单词将彼此“接近”。因此,如果您稍后打算将您的实现扩展为允许单词完成 - TreeSet 是一个更好的选择,因为您可以使用 tailSet() 方法。
TreeSet 也不会受到O(n) 的最坏情况复杂性的影响,因此如果latency 是您的系统中的一个问题 - 他们应该优先于需要O(n) 操作偶尔维护的HashSets数据结构。

此外,您可以使用ArrayList - 并确保使用Collections.sort() 对其进行排序。它应该可以解决问题,因为您的字典是静态的,而 Sets 更专注于动态(不断变化的字典)。稍后您可以使用 Collections.binarySearch() 查找某个单词是否在列表中

针对字符串优化的其他数据结构有TrieRadix tree(一种更节省空间的 trie 变体)。但是 - 这些没有在内置的 java Collections 库中实现。如果您稍后发现性能问题,并且需要加快代码的这个特定部分 - 您应该考虑切换到非内置数据结构,但作为初学者 - 让事情正常运行,不要过早优化它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多