我一直致力于开发一些字符流,形成单词,创建单词数组,然后创建一个包含每个唯一单词及其出现次数的向量(基本上是单词计数器)。
无论如何,我很长一段时间没有使用过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。
第一种方法在迭代元素方面会做得更多,但第二种方法需要你添加和删除向量的组件(我认为?)所以我不知道哪个更有效,或者是否值得考虑。
答案 0 :(得分:5)
为什么不使用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复制)
答案 1 :(得分: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());
进行排序
答案 2 :(得分:0)
如何使用google guava库?
Multiset<String> multiset = HashMultiset.create();
for (String word : words) {
multiset.add(word);
}
int countFoo = multiset.count("foo");
来自他们的javadocs:
支持与顺序无关的相等性的集合,如Set,但可能包含重复的元素。 multiset有时也被称为包。
够简单吗?