【问题标题】:How to sort two arrays but keep them in a corresponding order?如何对两个数组进行排序但保持相应的顺序?
【发布时间】:2020-05-04 22:28:58
【问题描述】:

在我的程序中,我接受了一个成绩列表和一个姓名列表。等级的顺序与名称的顺序相对应。我想将成绩从最低到最高或从最高到最低排序(没关系),但要保持它,以便人 a 和人 a 的成绩的索引相同。

【问题讨论】:

  • 不要。将成绩和姓名组合到您自己类型的列表中,例如学生。

标签: java arrays sorting


【解决方案1】:

首先,由于您使用的是 Java,自然的方法是创建一个类,例如学生,具有年级和姓名实例成员。然后,您将拥有一个可以排序的学生列表,这自然会将关联的数据保存在一起。

但是,如果您需要坚持使用单独的列表,诀窍是将索引列表排序到成绩列表中,而不是成绩列表本身。在比较器中,您比较的是成绩列表中相应位置的成绩,而不是索引。

List<String> grades = Arrays.asList("F", "A", "C", "D");
List<String> names = Arrays.asList("Tom", "Sue", "Dick", "Harry");

List<Integer> indexes = new ArrayList<>();
for(int i=0; i<grades.size(); i++) indexes.add(i);

indexes.sort((i1, i2) -> grades.get(i1).compareTo(grades.get(i2)));

for(Integer i : indexes)
    System.out.format("%s : %s%n", names.get(i), grades.get(i));

List<String> sortedGrades = new ArrayList<>();
List<String> sortedNames = new ArrayList<>();
for(Integer i : indexes) 
{
    sortedGrades.add(grades.get(i));
    sortedNames.add(names.get(i));
}

System.out.println();
System.out.println(sortedNames);
System.out.println(sortedGrades);

输出:

Sue : A
Dick : C
Harry : D
Tom : F

[Sue, Dick, Harry, Tom]
[A, C, D, F]

只是为了比较,下面是使用 Student 类的方法:

class Student
{
    String grade;
    String name;
    public Student(String name, String grade)
    {
        this.name = name;
        this.grade = grade;

    }
}

测试:

List<String> grades = Arrays.asList("F", "A", "C", "D");
List<String> names = Arrays.asList("Tom", "Sue", "Dick", "Harry");

List<Student> students = new ArrayList<>();
for(int i=0; i<grades.size(); i++) 
    students.add(new Student(names.get(i), grades.get(i)));

students.sort((s1, s2) -> s1.grade.compareTo(s2.grade));

for(Student s : students)
    System.out.format("%s : %s%n", s.name, s.grade);

输出:

Sue : A
Dick : C
Harry : D
Tom : F

【讨论】:

    【解决方案2】:

    说明

    最好创建一个对象来表示您的学生(其中将包含姓名和成绩作为属性),而不是尝试同步不同数组的顺序。

    考虑到您的两个数组的顺序已经相同(grades[0] 匹配 names[0] 等等),您基本上需要:

    • 迭代其中一个数组以创建学生列表;
    • 创建一个Comparator 以按升序对您的列表进行排序,或者创建一个Comparator.reversed() 如果您按降序对其进行排序;

    示例

    Student.java

    package com.stackoverflow;
    
    import java.math.BigDecimal;
    
    public class Student {
    
        private String name;
    
        private BigDecimal grade;
    
        public Student(String name, BigDecimal grade) {
            this.name = name;
            this.grade = grade;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public BigDecimal getGrade() {
            return grade;
        }
    
        public void setGrade(BigDecimal grade) {
            this.grade = grade;
        }
    
    }
    

    GradeComparator.java

    package com.stackoverflow;
    
    import java.util.Comparator;
    
    public class GradeComparator implements Comparator<Student> {
    
        @Override
        public int compare(Student source, Student target) {
            return source.getGrade().compareTo(target.getGrade());
        }
    
    }
    

    Example.java

    package com.stackoverflow;
    
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Example {
    
        public static void main(String[] args) {
    
            String[] names = {"John", "Mary", "Paul", "Alex"};
    
            BigDecimal[] grades = {BigDecimal.valueOf(5), BigDecimal.valueOf(3), BigDecimal.valueOf(8), BigDecimal.valueOf(2)};
    
            List<Student> studentList = new ArrayList<>();
    
            for (int i = 0; i < names.length; i++) {
                studentList.add(new Student(names[i], grades[i])); // make sure arrays have the same size so you don't get an ArrayOutOfBoundsException
            }
    
            studentList.sort(new GradeComparator()); // list is now sorted in ascending order
    
            studentList.sort(new GradeComparator().reversed()); // list is now sorted in descending order
    
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      这个任务你可以使用键索引计数排序,算法的运行时间是linear,我假设你在浮点数后面最多有2个小数所以我使用Number * 100

       public static void main(String[] args) {
              String[] names = { "Jack", "Sara", "Smith", "Nour", "Salah" };
              double[] degrees = new double[] { 90.0, 98.6, 98.5, 85.6, 100.0 };
              int N = degrees.length;
              int R = 101 * 100;
              int[] count = new int[R + 1];
              double[] aux = new double[N];
              String[] aux2 = new String[N];
              for (int i = 0; i < N; i++) {
                  int pos = (int) (degrees[i] * 100) + 1;
                  count[pos]++;
              }
      
              for (int r = 0; r < R; r++)
                  count[r + 1] += count[r];
      
              for (int i = 0; i < N; i++) {
                  int pos = (int) (degrees[i] * 100);
                  aux[count[pos]] = degrees[i];
                  aux2[count[pos]++] = names[i];
              }
      
              for (int i = 0; i < N; i++) {
                  degrees[i] = aux[i];
                  names[i] = aux2[i];
              }
      
              for (int i = 0; i < N; i++) {
                  System.out.print(names[i] + ": ");
                  System.out.println(degrees[i]);
              }
          }
      

      ,输出

      Nour: 85.6
      Jack: 90.0
      Smith: 98.5
      Sara: 98.6
      Salah: 100.0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-19
        • 2021-04-13
        • 2014-07-22
        • 2021-04-15
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        相关资源
        最近更新 更多