2010-12-16 3 views
0

У меня есть одна проблема для подсчета слов в Java.Java-счетчик слов

У меня есть карта

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

строка является именем файла, тогда как 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.

Примечание: это не задание!

ответ

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 

Btw, конвенция Java рекомендует верблюжьей случай стиль для идентификаторов.

+0

возможно, если (! Wc.containsKey (word)) wc.put (word, 1); else wc.put (word, wc.get (word) +1); `? Или `get; check null, put 1, else got + 1`? – khachik 2010-12-16 16:49:42

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

Есть много способов, вы можете сделать это, позвольте мне объяснить вам путь, который является одновременно эффективным и легко понять .. и конечно же 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 с помощью wordmap.get ("word");
  4. если вывод равен нулю, то вы знаете его новое слово.
  5. поставить слово на карте и поставить MutableInt в его стоимости с использованием
  6. wordmap.put ("слово», новый MutableInt());
  7. если выход не является нулевым, то вы знаете, что это не новое слово так увеличит счетчик, используя wordMap.getValue («word») .increase();
  8. Как только вы закончите делать это со всеми словами в файле, вы хотите поместить wordMap в fileMap, используя fileMap.put ("filename", wordMap);
Смежные вопросы