使用比较器进行排序

时间:2016-11-01 00:56:10

标签: sorting comparator

我尝试创建一个小程序来获取输入1-3,并根据用户选择的内容使用不同的排序算法对联系人列表进行排序。我已经编写了所有代码,但是当我尝试使用我的类别时,我遇到了问题。如果我使用集合排序,程序运行正常,但我需要使用这三种算法。

public class  {

public static void main(String[] args) {

    Contact[] contacts = {

    };


    int input;
    do{
    Scanner in = new Scanner(System.in);
    System.out.println("Sort by last name:     [0]");
    System.out.println("Sort by first name:    [1]");
    System.out.println("Sort by age:           [2]");
    System.out.println("Enter an option or 0 to end input: ");
    input = in.nextInt();

        if(input == 0)
        {
            System.out.println("Exiting...");
            System.exit(input);
        }

        else if(input == 1)
        {
            Merge.sort(contacts, new LastNameComparator());

            for(Contact contact : contacts)
            {
                System.out.println(contact);
            }
        }

        else if(input == 2)
        {
            Quick.sort(contacts, new FirstNameComparator());

            for(Contact contact : contacts)
            {   
                System.out.println(contact);
            }
        }

        else if(input == 3)
        {
            Heap.sort(contacts, new AgeComparator());

            for(Contact contact : contacts)
            {
                System.out.println(contact);
            }
        }

        else if(input > 3 || input < 0)
        {
            System.out.println("Invalid entry");
        }

    } while (input != 0);
}

}

    public class Contact implements Comparable{
    import java.util.Comparator;

    String lastName;
    String firstName;
    String homeState;
    Integer age;

    Contact(String lastName, String firstName, String homeState, Integer age)
    {
        this.lastName = lastName;
        this.firstName = firstName;
        this.homeState = homeState;
        this.age = age;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getHomeState() {
        return homeState;
    }

    public void setHomeState(String homeState) {
        this.homeState = homeState;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return String.format("%8s %8s %7s, %7d", this.lastName, this.firstName, this.homeState, this.age);
    }

    class FirstNameComparator implements Comparator<Contact> {
        public int compare(Contact a, Contact b) {
            return a.firstName.compareToIgnoreCase(b.firstName);
            }

    class LastNameComparator implements Comparator<Contact>{
         public int compare(Contact a, Contact b) {
            return a.lastName.compareToIgnoreCase(b.lastName);
            }

    class AgeComparator implements Comparator<Contact> {
         public int compare(Contact a, Contact b) {
            return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
            }

        }
    }
}

}

非常感谢任何提示。谢谢!

2 个答案:

答案 0 :(得分:0)

@Mark,以下是我所做的更改。

  1. 使用Comparator和Comparable时有些含糊不清,您可以阅读此帖并查看差异:What is the difference between compare() and compareTo()?

  2. 您的索引错误,例如0到'按姓氏排序'和'退出'

  3. 导入始终在类声明

  4. 之前
  5. 缺少一些括号

  6. 4.5 Heap中有一个主要方法,Assignment1中的其他选项只是为了编译而删除了

    1. 我建议您使用Generics来创建这个课程,您可以在这里阅读更多内容:https://docs.oracle.com/javase/tutorial/java/generics/。在你的Head.sort方法中,你定义它接收一个Comparable并且你传递的是Comparable和Comparator,就像我说的那样,它的含糊不清。它更好地传递一个通用数组(像任何东西 - &gt; String [],int [],yourOwnClass [])并提供第二个参数:比较器!所以,让我们回去,改为使用泛型并提供你的比较器!现在,您调用方法sort并说明要比较的参数是什么(Comparator)。您可以在此处查看最终结果:

      import java.util.Scanner;     公共课Assignment1 {

      public static void main(String[] args) {
      
      Contact[] contacts = {
              new Contact("Collins", "Kelly", "Illinois", 26),
              new Contact("Smith", "Brandon", "Michigan", 32),
              new Contact("Jones", "Mark", "California", 29),
              new Contact("McDowell", "Ryan", "Texas", 30),
              new Contact("Thompson", "April", "New York", 35)
      };
      
      
      int input;
      do {
          Scanner in = new Scanner(System.in);
          System.out.println("Sort by last name:     [1]");
          System.out.println("Sort by first name:    [2]");
          System.out.println("Sort by age:           [3]");
          System.out.println("Enter an option or 0 to end input: ");
          input = in.nextInt();
      
          if (input == 0) {
              System.out.println("Exiting...");
              System.exit(input);
          } else if (input == 3) {
              Heap.sort(contacts, new Contact.AgeComparator());
      
      
              for (Contact contact : contacts) {
                  System.out.println(contact);
              }
          } else if (input > 3 || input < 0) {
              System.out.println("Invalid entry");
          }
      
      } while (input != 0);
      

      } }

    2. 联系班级:

      import java.util.Comparator;
      

      公共课程联络{

      String lastName;
      String firstName;
      String homeState;
      Integer age;
      
      Contact(String lastName, String firstName, String homeState, Integer age) {
          this.lastName = lastName;
          this.firstName = firstName;
          this.homeState = homeState;
          this.age = age;
      }
      
      public String getLastName() {
          return lastName;
      }
      
      public void setLastName(String lastName) {
          this.lastName = lastName;
      }
      
      public String getFirstName() {
          return firstName;
      }
      
      public void setFirstName(String firstName) {
          this.firstName = firstName;
      }
      
      public String getHomeState() {
          return homeState;
      }
      
      public void setHomeState(String homeState) {
          this.homeState = homeState;
      }
      
      public Integer getAge() {
          return age;
      }
      
      public void setAge(Integer age) {
          this.age = age;
      }
      
      @Override
      public String toString() {
          return String.format("%8s %8s %7s, %7d", this.lastName, this.firstName, this.homeState, this.age);
      }
      
      static class FirstNameComparator implements Comparator<Contact> {
          public int compare(Contact a, Contact b) {
              return a.firstName.compareToIgnoreCase(b.firstName);
          }
      }
      
      static class LastNameComparator implements Comparator<Contact> {
          public int compare(Contact a, Contact b) {
              return a.lastName.compareToIgnoreCase(b.lastName);
          }
      }
      
      static  class AgeComparator implements Comparator<Contact> {
          public int compare(Contact a, Contact b) {
              return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
          }
      
      }
      }
      

      堆类

      import java.util.Comparator;
      

      公共类堆{

      // This class should not be instantiated.
      private Heap() { }
      
      /**
       * Rearranges the array in ascending order, using the natural order.
       * @param pq the array to be sorted
       */
      public static <T> void sort(T[] pq, Comparator<T> comparator) {
          int n = pq.length;
          for (int k = n/2; k >= 1; k--)
              sink(pq, k, n, comparator);
          while (n > 1) {
              exch(pq, 1, n--);
              sink(pq, 1, n, comparator);
          }
      }
      
      private static <T> void sink(T[] pq, int k, int n, Comparator<T> comparator) {
          while (2*k <= n) {
              int j = 2*k;
              if (j < n && less(pq, j, j+1, comparator)) j++;
              if (!less(pq, k, j, comparator)) break;
              exch(pq, k, j);
              k = j;
          }
      }
      
      
      private static <T> boolean less(T[] pq, int i, int j, Comparator<T> comparator) {
          return comparator.compare(pq[i-1],pq[j-1]) < 0;
      }
      
      private static void exch(Object[] pq, int i, int j) {
          Object swap = pq[i-1];
          pq[i-1] = pq[j-1];
          pq[j-1] = swap;
      }
      
      }
      

      合并

          import java.util.Comparator;
      
      public class Merge {
      
          // This class should not be instantiated.
          private Merge() {
          }
      
          // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
          private static <T> void merge(T[] a, T[] aux, int lo, int mid, int hi, Comparator<T> comparator) {
              // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
              assert isSorted(a, lo, mid, comparator);
              assert isSorted(a, mid + 1, hi, comparator);
      
              // copy to aux[]
              for (int k = lo; k <= hi; k++) {
                  aux[k] = a[k];
              }
      
              // merge back to a[]
              int i = lo, j = mid + 1;
              for (int k = lo; k <= hi; k++) {
                  if (i > mid) a[k] = aux[j++];
                  else if (j > hi) a[k] = aux[i++];
                  else if (less(aux[j], aux[i], comparator)) a[k] = aux[j++];
                  else a[k] = aux[i++];
              }
      
              // postcondition: a[lo .. hi] is sorted
              assert isSorted(a, lo, hi, comparator);
          }
      
          // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
          private static <T> void sort(T[] a, T[] aux, int lo, int hi, Comparator<T> comparator) {
              if (hi <= lo) return;
              int mid = lo + (hi - lo) / 2;
              sort(a, aux, lo, mid, comparator);
              sort(a, aux, mid + 1, hi, comparator);
              merge(a, aux, lo, mid, hi, comparator);
          }
      
          /**
           * Rearranges the array in ascending order, using the natural order.
           *
           * @param a the array to be sorted
           */
          public static <T> void sort(T[] a, Comparator<T> comparator) {
              T[] aux = (T[])new Object[a.length];
              sort(a, aux, 0, a.length - 1, comparator);
              assert isSorted(a, comparator);
          }
      
          // is v < w ?
          private static <T> boolean less(T v, T w, Comparator<T> comparator) {
              return comparator.compare(v,w) < 0;
          }
      
      
          private static <T> boolean isSorted(T[] a, Comparator<T> comparator) {
              return isSorted(a, 0, a.length - 1, comparator);
          }
      
          private static <T> boolean isSorted(T[] a, int lo, int hi, Comparator<T> comparator) {
              for (int i = lo + 1; i <= hi; i++)
                  if (less(a[i], a[i - 1], comparator)) return false;
              return true;
          }
      }
      

      快速

          import java.util.Comparator;
      
      public class Quick {
          // This class should not be instantiated.
          private Quick() {
          }
      
          /**
           * Rearranges the array in ascending order, using the natural order.
           *
           * @param a the array to be sorted
           */
          public static <T> void sort(T[] a, Comparator<T> comparator) {
              sort(a, 0, a.length - 1, comparator);
              assert isSorted(a, comparator);
          }
      
          // quicksort the subarray from a[lo] to a[hi]
          private static <T> void sort(T[] a, int lo, int hi, Comparator<T> comparator) {
              if (hi <= lo) return;
              int j = partition(a, lo, hi, comparator);
              sort(a, lo, j - 1, comparator);
              sort(a, j + 1, hi, comparator);
              assert isSorted(a, lo, hi, comparator);
          }
      
          // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
      // and return the index j.
          private static <T> int partition(T[] a, int lo, int hi, Comparator<T> comparator) {
              int i = lo;
              int j = hi + 1;
              T v = a[lo];
              while (true) {
      
                  // find item on lo to swap
                  while (less(a[++i], v, comparator))
                      if (i == hi) break;
      
                  // find item on hi to swap
                  while (less(v, a[--j], comparator))
                      if (j == lo) break;      // redundant since a[lo] acts as sentinel
      
                  // check if pointers cross
                  if (i >= j) break;
      
                  exch(a, i, j);
              }
      
              // put partitioning item v at a[j]
              exch(a, lo, j);
      
              // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
              return j;
          }
      
          /**
           * Rearranges the array so that {@code a[k]} contains the kth smallest key;
           * {@code a[0]} through {@code a[k-1]} are less than (or equal to) {@code a[k]}; and
           * {@code a[k+1]} through {@code a[n-1]} are greater than (or equal to) {@code a[k]}.
           *
           * @param a the array
           * @param k the rank of the key
           * @return the key of rank {@code k}
           */
          public static <T> T select(T[] a, int k, Comparator<T> comparator) {
              if (k < 0 || k >= a.length) {
                  throw new IndexOutOfBoundsException("Selected element out of bounds");
              }
              int lo = 0, hi = a.length - 1;
              while (hi > lo) {
                  int i = partition(a, lo, hi, comparator);
                  if (i > k) hi = i - 1;
                  else if (i < k) lo = i + 1;
                  else return a[i];
              }
              return a[lo];
          }
      
      
          // is v < w ?
          private static <T> boolean less(T v, T w, Comparator<T> comparator) {
              return comparator.compare(v, w) < 0;
          }
      
          // exchange a[i] and a[j]
          private static  void exch(Object[] a, int i, int j) {
              Object swap = a[i];
              a[i] = a[j];
              a[j] = swap;
          }
      
      
          private static <T>  boolean isSorted(T[] a, Comparator<T> comparator) {
              return isSorted(a, 0, a.length - 1, comparator);
          }
      
          private static <T> boolean isSorted(T[] a, int lo, int hi, Comparator<T> comparator) {
              for (int i = lo + 1; i <= hi; i++)
                  if (less(a[i], a[i - 1], comparator)) return false;
              return true;
          }
      }
      

答案 1 :(得分:0)

看到你在

中传递了两个参数
 Heap.sort(contacts, new AgeComparator());

现在,如果您看到Heap类的排序方法

public static void sort(Comparable[] pq) {
int n = pq.length;
for (int k = n/2; k >= 1; k--)
    sink(pq, k, n);
while (n > 1) {
    exch(pq, 1, n--);
    sink(pq, 1, n);
}

它只接受一个参数,因此您需要为两个参数修改它。    如果您需要,请参考:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collections.java#Collections.sort%28java.util.List%2Cjava.util.Comparator%29