4

私は最近、並べ替えアルゴリズムと、さまざまな種類の入力との関係についての理解を深めるために取り組んでいます。現在、私は各学生が姓、GPA、およびユーザー ID (文字列、倍精度、整数) の 3 つのパラメーターを持つ学生管理プログラムに取り組んでいます。それらはそれぞれ、これら 3 つのパラメーターを持つ Student クラスに格納され、何十もの生徒がいます (プログラムの重要な機能は、生徒の入力、削除、および更新です)。

私の質問は: 主要な並べ替えアルゴリズム (mergesort、quicksort など) を使用して、各パラメーターで生徒のリストを並べ替える最良の方法は何ですか? たとえば、マージソートを実行してリストをGPAでソートする最良の方法は何ですか? または、クイックソートを使用してリストを姓でソートしますか?

基本的に、私の質問は次のようになります...これらのオブジェクトに 3 つのパラメーターがなければ、これらのオブジェクトを並べ替えることができます (100 個の数値を並べ替えるためのマージソートを作成するのは非常に簡単です)。他の 2 つのパラメーターを管理し、並べ替え後にアクセスできるようにするにはどうすればよいですか?

4

6 に答える 6

5

Java でこれを行う方法は、異なるComparatorsを使用することです。次に、次のように言います。

Collections.sort(list, new NameComparator());

または

Collections.sort(list, new GpaComparator());

これらのコンパレータは、異なるフィールドを使用して 2 つの要素間の順序を定義します。

たとえば、Name Comparator は次のようになります。

class NameComparator implements Comparator< Student> {
    @Override public int compare(Student left, Student right) {
        return left.getName().compareTo(right.getName());
    }
}

そしてGpaComparatorは

class GpaComparator implements Comparator< Student> {
    @Override public int compare(Student left, Student right) {
        if (left.getGpa() < right.getGpa()) {
            return -1;
       } else if (left.getGpa() > right.getGpa()) {
            return 1;
       } else {
           return 0;
     }
 }
于 2012-04-04T17:49:20.413 に答える
1

これはおそらく話題から外れていますが、何かクールなことを試したい場合は、JDK 8 Lambda Previewが、 Lamda式とメソッド参照を使用してコンパレーターを定義するためのいくつかのクールな方法を提供します。

クラスがあるとしましょう:

class Jedi  {
   private final String name;
   private final int age;
   //...
}

そしてそれらのコレクション:

List<Jedi> jediAcademy = asList(new Jedi("Obiwan",80), new Jedi("Anakin", 30));
sort(jediAcademy, (j1, j2) -> j1.getAge() > j2.getAge() ? 1 : j1.getAge() < j2.getAge() ? -1 : 0);
System.out.println(jediAcademy); //Anakin, Obiwan

または、メソッド参照を使用して、Jediにコンパレータとして動作するメソッドがあると仮定します(同じシグニチャ)

class Jedi  {
  public static int compareByAge(Jedi first, Jedi second){
     return first.age > second.age ? 1 : first.age < second.age ? -1 : 0;
  }
   //...
}

これは、メソッド参照を使用してコンパレータを生成するために次のように使用できます。

List<Jedi> jediAcademy = asList(new Jedi("Obiwan",80), new Jedi("Anakin", 30));
sort(jediAcademy, Jedi::compareByAge);
System.out.println(jediAcademy);//Anakin, Obiwan
于 2012-04-04T18:18:18.880 に答える
1

このようにクラスにComparableインターフェースを実装することをお勧めしますStudent

public class Student implements Comparable {
   public int compareType; //you can make this an enum if you want
   ...

   public int compareTo(Object o) {
       if(compareType == 0) 
         return gpaCompareTo(o);
       else if(compareType == 1)
         return nameCompareTo(o);

       return idCompateTo(o); 
   }

   public int gpaCompareTo(Object o) {
       //implement your gpaCompareTo
   }

   public int nameCompareTo(Object o) {
       //implement your nameCompareTo
   }

   public int idCompareTo(Object o) {
       //implement your idCompareTo
   }
}

そして、次のような組み込みの並べ替えを使用します

List<Student> list = new ArrayList<Student>();
...
Collections.sort(list);

Comparableまたは、独自のコンパレータを実装して設計することはできません

public class MyComparator implements Comparator<Student> {

   public int compare(Student o1, Student o2) {
      //implement the comparator
   }

   public boolean equals(Object o) {
      //implement the equals 
   }
}

Collection's次に、他の並べ替え方法を使用できます

Collections.sort(list, MyComparator);
于 2012-04-04T17:48:57.700 に答える
1

これを行う典型的な方法は、 を受け入れる任意の型で一般的なソート アルゴリズムを記述してComparatorから、異なるComparators を記述して異なるフィールドでソートすることです。

于 2012-04-04T17:49:10.097 に答える
0

数値の並べ替えとまったく違いはありませんが、この場合、「桁」はユーザーの 3 つのフィールドであり、各桁の値は各フィールドの値によって制限され、フィールドの順序によって並べ替えの順位が決まります。

もう少し具体的に言うと、次の 3 つのフィールドを持つタプルがあり、<GPA, Last Name, User ID>GPA、姓、ユーザー ID の順で並べ替えるとします。

<3.75, Jones, 5>219 が 139 の上でソートされるのと同じ方法で (つまり、「10 の」桁が低くても、「100 の」桁はより高い値を持ちます)、<3.0, Adams, 2>「GPA の桁」(これはより多くの「名字の数字」が低いにもかかわらず、より高い値を持っています (たとえば、Jones は Adams よりも「低い」)。

于 2012-04-04T17:48:10.117 に答える