0

How to sort 1D (String) array and 2D (int) array based on 1D (double) array with Bubble Sort in Java. I managed to sort String array based on double array but can't figure out how to also sort 2D (int) array. Every row in 2D array (grades) represents each students multiple grades. I need to achieve goal by using this kind of structure (three arrays). Everything needs to be sorted depending on finalGrade array.

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;
                }
           }
        } 
} 
  • At this point, why not create a Student class, add grades as a 1D array field and final grade as an int field then create your array of Students and do the sort that way. – David Tejuosho Jan 25 '22 at 20:32
  • I know, your suggestion is much better... but can it be sorted this way? – Bugsters104 Jan 25 '22 at 20:35
  • yes it can. I'm writing an answer now – David Tejuosho Jan 25 '22 at 20:39
  • The trick is to *not* sort the 2D array directly. Sort an array of indexes, numbers from `0` to `n-1`, according to the sort criteria for the 2D array. Then use the index array to generate the sorted elements. The issue is that I've only written a [C++ solution](https://stackoverflow.com/questions/46382252/sort-array-by-first-item-in-subarray-c/46382976#46382976), but the principle is the same. – PaulMcKenzie Jan 25 '22 at 20:46

3 Answers3

1

As was mentioned, sorting indices would be easier with fewer items to swap. But better would be to:

  • use a class (as also suggested).
  • implement a quick sort or equivalent (or use the ones in the API).

Here is some data. There is no relationship between grades and final grades.

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}; 

Now sort and print

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])); 
}

prints

   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]


  • this method returns the indices for use in printing the results. If a class were used then the index sort wouldn't be required since. Then the list or array of objects could be returned.

  • initialize the index list from 0 to length of arrays.

  • this works the same way as any bubble or selection sort except that indices array is used to index into the finalGrade array and the indices are swapped based on the result of the comparison.

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;
}

The above is actually a variation of a selection sort. Your loop parameters don't work and your implementation has other problems. You can still apply the above to a Bubble-sort

WJS
  • 36,363
  • 4
  • 24
  • 39
0

If you must do it in this manner then sorting the 2D array is no harder than sorting any other array. You have to remember that a 2D array is just an array of arrays. i.e just treat the inner array the way you would treat any other object in an array.

    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
                }
            }
        }
    }

I will say that I think this is not a good way at all to solve this problem. abstracting this in a class would be much better.

David Tejuosho
  • 177
  • 1
  • 14
  • 1
    *I will say that I think this is not a good way at all to solve this problem* -- The better way to solve the problem is to sort an index array, not the 2D array itself. – PaulMcKenzie Jan 25 '22 at 20:48
  • Thank you, can you please explain me why it is working? For example this line: tempIndex = indices[j];? tempIndex is 1D array but here it is used jus like a casual variable and grades[j] is used like 1D array istead of 2D array. – Bugsters104 Jan 26 '22 at 16:47
  • I didn't use tempIndex in my code but I'll assume you're talking about the other answers tempIndex is not an array. It's an int. indices is a 1D array of ints. This means that each member ```indices [i]``` is an int. grades is a 2D array of ints. This means that each member ```grades [j]``` is its own array. So when you call grades [j], you are calling a 1D array. You can treat that array like any other object/member. – David Tejuosho Jan 26 '22 at 20:28
0

As mentioned in the comments, the better, less cluttered way of sorting a 2D array would be to sort an array of indices numbered 0 to n-1, where n is the total number of items.

Then at the end, use the indices to point to, or even regenerate the 2D array.

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]]);
} 

Note that you do not have to swap multiple arrays, as the index array points to the sorted item.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45