使用两个不同的标准对数组进行排序

时间:2012-04-13 01:52:04

标签: java arrays sorting

我正在尝试使用插入排序算法对数组进行排序。数组中包含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());
    }
}

4 个答案:

答案 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;
     }