【问题标题】:How to sort 2D array in Java based on 1D array values如何根据一维数组值在Java中对二维数组进行排序
【发布时间】:2022-01-25 20:20:47
【问题描述】:

如何在 Java 中使用冒泡排序基于一维(双)数组对一维(字符串)数组和二维(整数)数组进行排序。 我设法根据双数组对字符串数组进行排序,但不知道如何对二维(int)数组进行排序。 二维数组(成绩)中的每一行代表每个学生的多个成绩。 我需要通过使用这种结构(三个数组)来实现目标。 一切都需要根据 finalGrade 数组进行排序。

static void sort(String[] students, int[][] grades, double[] finalGrade) {
        double tempFG;
        String tempStud;
        int t;

        //Bubble Sort
        for (int i=0; i<students.length-1; i++) {
            for (int j=0; j<finalGrade.length-i-1; j++) { 
                if (finalGrade[j] < finalGrade[j+1]) { 
                    tempFG = finalGrade[j];
                    tempStud = students[j];
                    finalGrade[j] = finalGrade[j+1];
                    students[j] = students[j+1];
                    finalGrade[j+1] = tempFG;
                    students[j+1] = tempStud;
                }
           }
        } 
} 

【问题讨论】:

  • 此时,为什么不创建一个 Student 类,将成绩添加为一维数组字段,将最终成绩添加为 int 字段,然后创建学生数组并按此方式进行排序。
  • 我知道,您的建议要好得多...但是可以这样排序吗?
  • 是的,它可以。我现在正在写答案
  • 诀窍是直接对二维数组进行排序。根据二维数组的排序标准,对索引数组进行排序,数字从0n-1。然后使用索引数组生成排序后的元素。问题是我只写了一个C++ solution,但原理是一样的。

标签: java arrays bubble-sort


【解决方案1】:

如前所述,如果要交换的项目更少,对索引进行排序会更容易。但更好的是:

  • 使用类(同样建议)。
  • 实现快速排序或等效(或使用 API 中的)。

这是一些数据。成绩和最终成绩之间没有关系。

String[] students = {"John", "May", "Helen", "Jim", "George"};
int[][] grades = {{88,97},{100,84},{80, 85},{92,91},{91,78}};
double[] finalGrade = {88.5, 92.6, 85.2, 89.3, 91.3}; 

现在排序和打印

int indices[] = sort(students, grades, finalGrade);
for (int i = 0; i < indices.length; i++) {
        int k = indices[i];
        System.out.printf("%6s -  %f  - %s%n",students[k], 
               finalGrade[k], Arrays.toString(grades[k])); 
}

打印

   May -  92.600000  - [100, 84]
George -  91.300000  - [91, 78]
   Jim -  89.300000  - [92, 91]
  John -  88.500000  - [88, 97]
 Helen -  85.200000  - [80, 85]


  • 此方法返回用于打印结果的索引。如果使用了一个类,那么从那以后就不需要索引排序了。然后可以返回对象列表或数组。

  • 0 to length of arrays初始化索引列表。

  • 这与任何冒泡排序或选择排序的工作方式相同,只是索引数组用于对 finalGrade 数组进行索引,并且索引会根据比较结果进行交换。

static int[] sort(String[] students, int[][] grades, double[] finalGrade) {
  
    //Bubble Sort
    int[] indices = new int[grades.length];
    Arrays.setAll(indices, i->i);

    for (int i=0; i<students.length-1; i++) {
        for (int j=i+1; j<finalGrade.length; j++) { 
            if (finalGrade[indices[i]] < finalGrade[indices[j]]) {
                int t = indices[j];
                indices[j] = indices[i];
                indices[i] = t;
            }
       }
    }
    return indices;
}

以上实际上是selection sort 的变体。您的循环参数不起作用,您的实现还有其他问题。您仍然可以将上述内容应用于Bubble-sort

【讨论】:

    【解决方案2】:

    如果您必须以这种方式进行,那么对二维数组进行排序并不比对任何其他数组进行排序更难。您必须记住,二维数组只是数组的数组。即像对待数组中的任何其他对象一样对待内部数组。

        static void sort(String[] students, int[][] grades, double[] finalGrade) {
            double tempFinalGrade;
            String tempStudent; //I think using well descriptive vars is better
            int [] tempGrade;
            
            //Bubble Sort
            for (int i=0; i<students.length-1; i++) {
                for (int j=0; j<finalGrade.length-i-1; j++) {
                    if (finalGrade[j] < finalGrade[j+1]) {
                        tempFinalGrade = finalGrade[j];
                        tempStudent = students[j]; 
                        tempGrade = grades[j];//addition
    
                        finalGrade[j] = finalGrade[j+1];
                        students[j] = students[j+1];
                        grades[j] = grades[j+1]; //addition
    
                        finalGrade[j+1] = tempFinalGrade;
                        students[j+1] = tempStudent;
                        grades[j+1] = tempGrade; //addition
                    }
                }
            }
        }
    

    我会说我认为这根本不是解决这个问题的好方法。在一个类中抽象这个会好得多。

    【讨论】:

    • 我会说我认为这根本不是解决这个问题的好方法 -- 解决问题的更好方法是对索引数组进行排序,而不是二维数组本身。
    • 谢谢,你能解释一下为什么它有效吗?例如这一行: tempIndex = indices[j];? tempIndex 是一维数组,但在这里它就像一个临时变量一样使用,而 Grades[j] 则像一维数组而不是二维数组一样使用。
    • 我没有在我的代码中使用 tempIndex 但我假设您在谈论其他答案 tempIndex 不是数组。这是一个整数。索引是一维整数数组。这意味着每个成员 indices [i] 都是一个 int。 Grades 是一个二维整数数组。这意味着每个成员grades [j] 都是它自己的数组。因此,当您调用等级 [j] 时,您调用的是一维数组。您可以像对待任何其他对象/成员一样对待该数组。
    【解决方案3】:

    如 cmets 中所述,对二维数组进行排序的更好、更简洁的方法是对编号为 0n-1 的索引数组进行排序,其中 n 是项目总数。

    然后在最后,使用索引指向,甚至重新生成二维数组。

    static void sort(String[] students, int[][] grades, double[] finalGrade) {
            int tempIndex;
            int[] indices = new int[finalGrade.length];
            for (int i = 0; i < finalGrade.length; ++i)
               indices[i] = i;
    
            //Bubble Sort
            for (int i=0; i<students.length-1; i++) {
                for (int j=0; j<finalGrade.length-i-1; j++) { 
                    if (finalGrade[indices[j]] < finalGrade[indices[j+1]]) { 
                        tempIndex = indices[j];
                        indices[j] = indices[j+1];
                        indices[j+1] = tempIndex;
                    }
               }
            } 
    
        // Output results 
        for (int i = 0; i < indices.length; ++i)
          System.out.println(students[indices[i]] + "  " + finalGrade[indices[i]]);
    } 
    

    请注意,您不必交换多个数组,因为索引数组指向已排序的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-08
      • 2023-01-31
      • 2015-08-25
      • 2017-05-25
      • 2014-07-30
      • 2019-09-09
      • 2022-01-10
      • 1970-01-01
      相关资源
      最近更新 更多