0

基本的な単語頻度カウンターを構築しています。コードを以下に示します。

public static List<Frequency> computeWordFrequencies(List<String> words) 
{
    List<Frequency> list_of_frequency = new ArrayList<Frequency>();
    List<String> list_of_words = words;
    int j = 0;
    for(int i=0; i<list_of_words.size(); i++)
    {

        String current_word = list_of_words.get(i);
        boolean added = false;
        if(list_of_frequency.size() == 0)
        {
            list_of_frequency.add(new Frequency(current_word, 1));
            System.out.println("added " + current_word);
        }
        else
        {

            System.out.println("Current word: " + current_word);
            System.out.println("Current Frequency: " + list_of_frequency.get(j).getText());
            if(list_of_frequency.contains(current_word))
            {
                list_of_frequency.get(j).incrementFrequency();
                System.out.println("found... incremented " + list_of_frequency.get(j).getText() + " frequency");
                added = true;
            }
            else
            {
                list_of_frequency.add(new Frequency(current_word, 1));
                System.out.println("added " + current_word);
                added = true;
            }
        }
    }
}

そして、私が得ている出力は次のとおりです。

added I
Current word: am
Current Frequency: I
added am
Current word: very
Current Frequency: I
added very
Current word: good
Current Frequency: I
added good
Current word: at
Current Frequency: I
added at
Current word: being
Current Frequency: I
added being
Current word: good
Current Frequency: I
added good
Total item count: 7
Unique item count: 7
I:1
am:1
very:1
good:1
at:1
being:1
good:1

したがって、「list_of_frequency」をループするには for ループが必要ですが、それを行うと、単語を繰り返し追加するなどの他の問題に遭遇します。私の論理はここにありますか?このプロジェクトを進めるためのより良い方法はありますか? 前もって感謝します!

4

6 に答える 6

2

クラスの頻度メソッドを使用してこれを行うことができますCollections

ここにサンプルがあります:

public void wordFreq(){
String text = "hello bye hello a bb a bye hello";

        List<String> list = Arrays.asList(text.split(" "));

        Set<String> uniqueWords = new HashSet<String> (list);
        for (String word : uniqueWords) {
            System.out.println(word + ": " + Collections.frequency(list, word));
        }
}
于 2013-01-12T22:37:19.440 に答える
1

You are over-complicating things.

You only need a few lines:

public static Map<String, Integer> getFrequencies(List<String> words) {
    Map<String, Integer> freq = new HashMap<String, Integer>();
    for (String word : words) {
        Integer i = freq.get(word);
        freq.put(word, i == null ? 1 : i + 1);
    }
    return freq;
}
于 2013-01-12T22:52:28.053 に答える
0

このコードを else 部分に追加します。あなたがすべきことは

  1. ループ内で、単語が既にリストにあるかどうかを確認します
  2. パート 1 が true の場合、その周波数をインクリメントするだけです
  3. そうでなければ、頻度1でリストに入れます

    for(j = 0; j < list_of_frequency.size; j++)
       if(list_of_frequency.get(i).getText().equals(current_word))
          list_of_frequency.get(i).frequency++; // increment frequency 
                                  //if word is already encountered before
    
于 2013-01-12T22:36:32.153 に答える
0

より速く実行するには、リストをソートすることから始まる別のアルゴリズムを使用する必要があると思います:

  1) sort your list of string (cf. java.util.Collections.sort())
  2) in pseudo code :
 iterate your sorted list
 current_word = word of current iteration
 if it's a new word (! current_word.equals( oldWord) )
 counter = 1
 if (current_word.equals( oldWord)) {
    counter++
     store current_word in variable oldWord 
 }
 when the word change create your Frequency(oldWord, counter) and add to the list of frequencies

そのため、頻度リストを毎回確認する必要はなく、1 つの単語に対して 1 回挿入するだけで済みます。

リスト list_of_frequency のすべてのエントリは一意の単語であるため、list_of_frequency のリストの代わりに Set を使用することもできます。

于 2013-01-12T22:38:09.953 に答える
0

メソッドをこれに置き換えます。データの分析中にマップを使用すると、パフォーマンスが大幅に向上します。

public static List<Frequency> computeWordFrequencies(List<String> words) {
    Map<String, Integer> counts = new HashMap<String, Integer>();
    for(String word : words) {
        Integer current = counts.get(word);
        if(current != null) {
            counts.put(word, current+1);
        }
        else counts.put(word, 1);
    }

    // Then, if you really need that list of Frequency
    List<Frequency> list_of_frequency = new ArrayList<Frequency>();

    for(String s : counts.keySet()) {
        list_of_frequency.add(new Frequency(s, counts.get(s)));
    }

    return list_of_frequency;
}
于 2013-01-12T22:38:46.430 に答える
0

I would proceed like this :

List<String> words = Arrays.asList("foo", "bar", "qux", "foo");

Map<String, AtomicInteger> frequencyMap = new HashMap<String, AtomicInteger>();
for (String word : words)
{
    AtomicInteger freq = frequencyMap.get(word);
    if (freq == null) {
        frequencyMap.put(word, new AtomicInteger(1));
    }
    else
    {
        freq.incrementAndGet();
    }
}

for (String word : frequencyMap.keySet())
{
    System.out.println(word + " :" + frequencyMap.get(word));
}

By using AtomicInteger you can easily increment your frequency counter.

于 2013-01-12T22:51:31.840 に答える