2012-04-13 9 views
1

挿入ソートアルゴリズムを使用して配列をソートしようとしています。配列は、wordフィールド(テキストファイルから入力)およびfrequencyフィールド(特定の単語がテキストファイルに現れる回数を測定する)を含むWordNode要素で満たされます。私は単語を頻度で並べ替えるように並べ替えを実装していますが、周波数が等しい場合はアルファベット順に並べ替える必要があります。どのようにして2つの異なる基準を同時に使用して並べ替えることができますか?以下は私のソートコードです。2つの異なる条件を使用して配列を並べ替える

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

ます。また 'Comparable'を実装する時に見ることができる、あなたは直接各ノードを比較し、' getWordは() 'String型の値を返します –

答えて

1

AppClayの答えは絶対に正しいですが、「それを片付け」に興味があるなら、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) 

だけでなく、これはコードが読みやすく、テスト作るん、それは別のスワップ・アウトすることになりました些細です必要に応じてコンパレータの実装。

+0

これは、Javaでコードを再作成すると(これはしばらくしています)うまくいけば、これを覚えています:) – joshuahealy

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()); 
} 
+1

一つの場所からの比較を制御することができます。文字列の値を減算しているので、 'cmp = sorted.peek()。getWord() - currentNode.getWord();'の行にどのように影響しますか? (決して気にしないで...ちょうどあなたの編集に気づいた) – lollercopter

+1

これはうまくいくとは思わないが、 'tmp'スタックの一番上から飛び出しているので、' cmp'の値をwhileループの中で更新する必要がある。しかし、もう一度、私は並べ替えを書いてからしばらくしています。 –

+0

'temp.push(sorted.pop());'行の後にforループ内のcmpを更新する必要はありません – joshuahealy

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))) { 
+0

私はこれが少し醜いことを認めます。比較のための関数を作成し、パラメータとして 'sorted.peek()'と 'currentNode'を渡す方が良いかもしれません。 – joshuahealy

+0

醜いと思うかもしれませんが、それはまだ完全に機能しています。私はプログラムで他の機能のいくつかを終えたら、ちょっとしたことをちょっと整理してみましょう。 – lollercopter

+0

私は他のオプションがそれをより読みやすく/保守可能にするために数行に渡って広げることだと思います。 – joshuahealy

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; 
    } 
関連する問題