我正在尝试使用插入排序算法对数组进行排序。数组中包含WordNode
个元素,其中包含word
字段(从文本文件输入)和frequency
字段(用于衡量特定单词在文本文件中出现的次数) )。我已经实现了排序,以便按频率(从最低到最高)对单词进行排序,但如果频率相等,我还想按字母顺序排序。如何同时使用两种不同的标准进行排序?下面是我的排序代码。
public static void sort(ArrayUnorderedList<WordNode> array) {
//create stacks for insertion sort
LinkedStack<WordNode> sorted = new LinkedStack<WordNode>();
LinkedStack<WordNode> temp = new LinkedStack<WordNode>();
//while the array has elements to be sorted
while(!array.isEmpty()) {
//remove current element from array
WordNode currentNode = array.removeFirst();
//while the sorted stack meets sorting criteria
while((!sorted.isEmpty()) && (sorted.peek().getFrequency() < currentNode.getFrequency())) {
//push elements to temp stack
temp.push(sorted.pop());
}
//push current element to sorted stack
sorted.push(currentNode);
//while the temp stack has elements to be replaced
while(!temp.isEmpty()) {
//push elements to sorted stack
sorted.push(temp.pop());
}
}
//replace sorted elements in array
while(!sorted.isEmpty()) {
array.addToRear(sorted.pop());
}
}
答案 0 :(得分:1)
AppClay的答案是绝对正确的,但是如果你有兴趣&#34;整理它&#34;,请创建一个实现Comparator的助手。
class WordNodeComparator implements Comparator<WordNode> {
@Override
public int compare(WordNode lhs, WordNode rhs) {
int result = lhs.getFrequency() - rhs.getFrequency();
if (result == 0) {
return lhs.getWord().compareTo(rhs.getWord());
}
else {
return result;
}
}
}
然后你只需创建一个实例,并在循环中使用它:
while((!sorted.isEmpty()) && (nodeComparator.compare(sorted.peek(), currentNode) < 0)
这不仅使代码更容易阅读和测试,而且根据需要交换不同的Comparator实现现在很简单。
答案 1 :(得分:0)
将此添加到您的代码中:
int cmp = sorted.peek().getFrequency() - currentNode.getFrequency();
if (cmp == 0)
cmp = sorted.peek().getWord().compareTo(currentNode.getWord());
while((!sorted.isEmpty()) && cmp < 0) {
//push elements to temp stack
temp.push(sorted.pop());
cmp = sorted.peek().getFrequency() - currentNode.getFrequency();
if (cmp == 0)
cmp = sorted.peek().getWord().compareTo(currentNode.getWord());
}
我假设getFrequency()
返回一个整数,并且WordNode
方法访问getWord()
中的实际单词。使用上面我们首先按频率进行比较,如果两个频率相等,那么我们按字母顺序进行比较
编辑:
一个更好的解决方案,定义这个辅助方法:
private static boolean compare(LinkedStack<WordNode> sorted, WordNode current) {
int cmp = sorted.peek().getFrequency() - current.getFrequency();
if (cmp == 0)
cmp = sorted.peek().getWord().compareTo(current.getWord());
return cmp;
}
然后将代码中的第一个内部循环更改为:
while (!sorted.isEmpty() && compare(sorted, currentNode) < 0) {
//push elements to temp stack
temp.push(sorted.pop());
}
答案 2 :(得分:0)
更新此行:
while((!sorted.isEmpty()) && (sorted.peek().getFrequency() < currentNode.getFrequency())) {
为:
while((!sorted.isEmpty()) && (sorted.peek().getFrequency() < currentNode.getFrequency() || (sorted.peek().getFrequency() == currentNode.getFrequency() && sorted.peek().getWord().compareTo(currentNode.getWord()) < 0))) {
答案 3 :(得分:0)
使用Guava lib:
public static List<WordNode> sort(List<WordNode> src){
List<WordNode> result = Lists.newArrayList(src);
Collections.sort(result, new Comparator<WordNode>(){
@Override public int compare(WordNode w1, WordNode w2) {
return ComparisonChain.start()
.compare(w1.frequency, w2.frequency)
.compare(w1.word , w2.word)
.result();
}});
return result;
}