繁体   English   中英

计算数组中单词的出现

[英]Counting occurrences of words in an array

我一直在研究一些需要处理的字符,这些字符组成单词,形成单词数组,然后创建一个向量,其中包含每个唯一的单词及其出现的次数(基本上是一个单词计数器)。

无论如何,我已经很久没有使用Java了,或者说实话很多编程都没有,我对当前的外观不满意。 我拥有的使矢量对我来说看起来很难看的部分,我想知道是否可以使它不那么混乱。

    int counter = 1;
    Vector<Pair<String, Integer>> finalList = new Vector<Pair<String, Integer>>();
    Pair<String, Integer> wordAndCount = new Pair<String, Integer>(wordList.get(1), counter); // wordList contains " " as first word, starting at wordList.get(1) skips it.

    for(int i= 1; i<wordList.size();i++){
        if(wordAndCount.getLeft().equals(wordList.get(i))){
            wordAndCount = new Pair<String, Integer>(wordList.get(i), counter++);
        }
        else if(!wordAndCount.getLeft().equals(wordList.get(i))){
            finalList.add(wordAndCount);
            wordAndCount = new Pair<String, Integer>(wordList.get(i), counter=1);
        }
    }
    finalList.add(wordAndCount); //UGLY!!

作为第二个问题,这给了我一个向量,所有单词都按字母顺序排列(如数组中一样)。 我想按出现顺序(在其中按字母顺序)进行排序。

最好的选择是:

  • 向下遍历向量,使用Collections.swap()将其与上面的一个进行比较,测试每个出现的int是否更高,然后检查上面的下一个(因为它现在已向上移动1),依此类推,直到不再大于上面的任何一个它。 任何出现的1都可以跳过。

  • 再次迭代向量,将每个元素相对于向量的第一个元素进行测试,然后向下迭代直到出现次数减少,然后将其插入到该元素之上。 所有出现的1将再次被跳过。

第一种方法在迭代元素方面会做更多的事情,但是第二种方法需要您添加和删除向量的分量(我认为吗?),所以我不知道哪种效率更高,或者它是否值得考虑。

为什么不使用Map来解决您的问题?

String[] words // your incoming array of words.
Map<String, Integer> wordMap = new HashMap<String, Integer>();
for(String word : words) {
  if(!wordMap.containsKey(word))
    wordMap.put(word, 1);
  else
    wordMap.put(word, wordMap.get(word) + 1);
}    

可以使用Java的排序集合来进行排序:

SortedMap<Integer, SortedSet<String>> sortedMap = new TreeMap<Integer, SortedSet<String>>();
for(Entry<String, Integer> entry : wordMap.entrySet()) {
  if(!sortedMap.containsKey(entry.getValue()))
    sortedMap.put(entry.getValue(), new TreeSet<String>());

  sortedMap.get(entry.getValue()).add(entry.getKey());
}

如今,您应该将排序留给该语言的库。 多年来,它们被证明是正确的。

请注意,由于涉及到所有数据结构,因此代码可能会占用大量内存,但这就是我们为高级编程所付出的代价(内存每秒钟变得越来越便宜)。

我没有运行代码来查看它是否有效,但是它确实可以编译(直接从eclipse复制)

关于:排序,一种选择是编写自定义Comparator ,该Comparator器首先检查每个单词出现的次数,然后(如果相等)按字母顺序比较单词。

private final class PairComparator implements Comparator<Pair<String, Integer>> {
    public int compareTo(<Pair<String, Integer>> p1, <Pair<String, Integer>> p2) {
        /* compare by Integer */
        /* compare by String, if necessary */
        /* return a negative number, a positive number, or 0 as appropriate */
    }
}

然后,您finalList通过调用Collections.sort(finalList, new PairComparator());finalList进行排序Collections.sort(finalList, new PairComparator());

如何使用Google番石榴库?

   Multiset<String> multiset = HashMultiset.create();
   for (String word : words) {
       multiset.add(word);
   }

   int countFoo = multiset.count("foo");

从他们的javadocs:

一个支持与顺序无关的相等的集合,例如Set,但可能具有重复的元素。 多重集合有时也称为袋。

很简单?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM