Счетчик слов Java - PullRequest
       26

Счетчик слов Java

0 голосов
/ 16 декабря 2010

У меня одна проблема с подсчетом слов в 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 ]

3 голосов
/ 16 декабря 2010

Google Библиотеки Гуавы имеют несколько очень полезных утилит и структур данных для такого рода проблем.

Чтобы разбить файл на слова, вы можете использовать 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 голос
/ 16 декабря 2010

Есть много способов сделать это, позвольте мне объяснить вам способ, который одновременно эффективен и прост для понимания ... и, конечно, ОО.

[Шаг 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 ('word', new MutableInt ());
  7. , если output не равен нулю, то вы знаете, что это не новое слово, поэтому увеличьте счетчик, используя wordMap.getValue ("word).увеличения ();
  8. Как только вы закончите делать это со всеми словами в файлевы хотите поместить wordMap в fileMap, используя fileMap.put ("filename", wordMap);
0 голосов
/ 16 декабря 2010

Вот пример, который должен помочь вам:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...