0

我一直在做一些事情,它需要一个字符流,形成单词,创建一个单词数组,然后创建一个包含每个唯一单词及其出现次数的向量(基本上是一个单词计数器)。

无论如何,我已经很长时间没有使用 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!!

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

最好的选择是:

  • 向下迭代向量,用上面的一个测试每个出现的 int,Collections.swap()如果它更高,然后检查上面的下一个(因为它现在向上移动 1),依此类推,直到它不再大于它上面的任何东西。可以跳过任何出现的 1。

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

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

4

3 回答 3

5

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

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 复制)

于 2012-07-16T14:40:42.277 回答
0

re:排序,一种选择是编写一个自定义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());

于 2012-07-16T14:46:43.323 回答
0

使用谷歌番石榴库怎么样?

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

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

从他们的javadocs:

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

够简单吗?

于 2012-07-16T15:53:19.707 回答