Java字计数器

时间:2010-12-16 16:30:47

标签: java dictionary information-retrieval

我在Java中计算单词有一个问题。

我有一张地图

Map<String,StringBuilder> files_and_text = new TreeMap<String,StringBuilder>();

String是文件名,而StringBuilder包含文件文本。

例如

StringBuilder file_tex = new StringBuilder();
StringBuilder file_tex2 = new StringBuilder();

file_text.append("some contents some file one");
files_and_tex.put("file1", file_text);

file_text2.append("test words test test words");    
files_and_tex.put("file2", file_text2);

现在我想制作一本可以告诉我的字典:

         |word 1 | word 2 | word 3 ........
file 1   | 3     |    1   |  0 .........
file 2   | 6     |    2   |  9 .........
.......
.......

单词1,2,3等是语料库单词。文件1,2,3等是文件名。此矩阵中的每个值表示此字在当前文件中出现的时间。

我最近从C迁移到Java,我知道如何编写凌乱的代码(结构化) 解决这个问题;我想知道如何在纯面向对象的风格中,特别是在Java中。

注意:这不是作业!

3 个答案:

答案 0 :(得分:3)

Google的Guava Libraries针对此类问题提供了一些非常有用的实用程序和数据结构。

要将文件拆分为单词,您可以使用Splitter:

Iterable<String> wordsInFile = 
   Splitter.on(' ').trimResuls().omitEmptyStrings().split(fileAsString);

要计算给定单词的出现次数,可以使用Multiset:

Multiset<String> countOfEachWord = HashMultiset.create();
countOfEachWord.addAll(wordsInFile);

您可以构建这两个部分来创建某种对象,如WordLookupTable。即:

public class WordLookupTable {

  private static final Splitter SPLITTER = Splitter.on(' ').trimResults().omitEmptyStrings();  
  private final Map<String, Multiset<String>> filenameToWordCountSet = Maps.newHashMap();

  public void addFile(String filename, String fileText) {
    Multiset<String> wordsInFile = getWordSetForFile(filename);

    for (String word : SPLITTER.split(fileText)) {
      wordsInFile.add(word);

    }
  }

  // Gets the count of all words for the file
  public long getCountOfWordsForFile(String filename) {
    return getWordSetForFile(filename).size();  

  }

  public long getCountOfWordInFile(String filename, String word) {
    return getWordSetForFile(filename).count(word);
  }

  public long getCountOfWordOverAllFiles(String word) {
    long count = 0;
    for (Multiset<String> wordSet : filenameToWordCountSet.values()) {
      count += wordSet.count(word);
    }
    return count;
  }

  private Multiset<String> getWordSetForFile(String filename) {
    Multiset<String> wordsInFile = filenameToWordCountSet.get(filename);
    if(wordsInFile == null) {
      wordsInFile = HashMultiset.create();
      filenameToWordCountSet.put(filename, wordsInFile);
    }
    return wordsInFile;
  }
}

答案 1 :(得分:1)

有很多方法可以做到这一点,让我向你解释一个有效且易于理解的方式......当然还有OO。

[步骤1]你必须有两个地图,一个存储文件特定数据,另一个存储文件名和文件数据。您可以选择任何您想要的文件而不是文件名。

private static HashMap<String, MutableInt> wordMap1 = new HashMap<String, MutableInt>();
private static HashMap<String, MutableInt> wordMap2 = new HashMap<String, MutableInt>();
private static HashMap<String, HashMap> fileMap = new HashMap<String, HashMap>();

[步骤2]制作MutableInt课程(从技术上讲,你想先做这个) 现在你可能会问什么是MutableInt,它是一个你将创建的类,以便你可以在遇到它时增加给定单词的值。

以下是MutableInt类的示例:

class MutableInt {
    int value = 1;
    public void increase () { ++value; }
    public int getValue () { return value; }
    public String toString(){
        return Integer.toString(value);
    }
}

[步骤3]现在,对于给定文件中的每个单词,执行以下操作:

  1. 为正在解析的文件创建一个新的wordMap
  2. 从文件中获取单词
  3. 使用wordmap.get(“word”);
  4. 检查word是否在wordMap中
  5. 如果输出为null,那么您就知道它是一个新词。
  6. 将该单词放入地图中,并使用
  7. 将MutableInt放入其值中
  8. wordmap.put('word“,new MutableInt());
  9. 如果输出不为null,那么你知道它不是一个新单词所以使用wordMap.getValue(“word).increase();
  10. 增加计数器
  11. 使用fileMap.put(“filename”,wordMap)后,要使用文件中的所有单词完成此操作,然后将wordMap放入fileMap;

答案 2 :(得分:0)

以下是一个可以帮助你的例子:

Map<String, StringBuilder> files_and_tex = new HashMap<String, StringBuilder>();

StringBuilder file_text = new StringBuilder();
StringBuilder file_text2 = new StringBuilder();
file_text.append("some contents some file one");
files_and_tex.put("file1", file_text);

file_text2.append("test words test test words");    
files_and_tex.put("file2", file_text2);

// Maps from file-name to word to count
Map<String, Map<String, Integer>> wordCounts =
        new HashMap<String, Map<String, Integer>>();

// Go through each filename (key in files_and_tex)
for (String file : files_and_tex.keySet()) {

    // Create a map to keep track of word counts for this file
    Map<String, Integer> wc = new HashMap<String, Integer>();
    wordCounts.put(file, wc);

    Scanner s = new Scanner("" + files_and_tex.get(file));
    while (s.hasNext()) {
        String word = s.next();
        if (!wc.containsKey(word))
            wc.put(word, 0);
        wc.put(word, wc.get(word) + 1);
    }
}

// And here is how to access the resulting data
System.out.println(wordCounts.get("file1").get("file")); // prints 1
System.out.println(wordCounts.get("file2").get("test")); // prints 3

顺便说一句,Java约定建议使用标识符的驼峰式样式。