Java help. Array sorting.

Associate
Joined
22 May 2004
Posts
1,792
Location
N.Ireland
Hi guys could anyone help me. I am writing this program in net beans for a night class and I have got the MArks to sort by ID but when I try to add anyother loop to get them to sort by ID and Marks it doesnt work Im not sure what im doing wrong.

Any chance anyone could add the loop so the ID's and the Marks sort. It only needs an extra loop for the marks.

Code:
/*
 *Class Name:Pc2
 *Project Name:Pc2
 *Package Name. pkgpc2
 *Created on 24 January 2008, 09:50
 *Version Number. 1.0
 *Author: Gareth McGibbon
 *Description:Program to sort out Syudent data for maths and english
 *Also has a menu option for useers to interact with. 
 */


        

package pkgpc2;
import keyb.InOut;

public class pkgpc2
{
    //================================================== ======== //
    // NAME : Array Data
    // RETURN TYPE : N/A
    // PARAMETERS : mathMark: Math students results
    //              engMark :English Students results
    //              mathId :Maths Student ID 
    //              engId :English Student ID
    // DESCRIPTION : The maths and english studentId and Marks. 
    // This is done as four arrays.
    //
    // //================================================== ========
    static void initialiseArrays(int[] mathMark, int[] engMark, String[] mathsId, String[] engId)
    {
        //Math Mark. Sample Data
        mathMark[0] = 72;
        mathMark[1] = 84;
        mathMark[2] = 21;
        mathMark[3] = 48;
        mathMark[4] = 55;
        mathMark[5] = 49;
        mathMark[6] = 78;
        mathMark[7] = 21;
        mathMark[8] = 35;
        mathMark[9] = 98;
        mathMark[10] = 44;
        mathMark[11] = 56;
        
        //Math ID. Sample Data
        mathsId[0] = "M1005";
        mathsId[1] = "M1002";
        mathsId[2] = "M1000";
        mathsId[3] = "M1003";
        mathsId[4] = "M1001";
        mathsId[5] = "M1004";
        mathsId[6] = "M1006";
        mathsId[7] = "M1010";
        mathsId[8] = "M1009";
        mathsId[9] = "M1008";
        mathsId[10] = "M1007";
        mathsId[11] = "M1011";
        
        
        //English Mark. Sample Data
        engMark[0] = 82;
        engMark[1] = 56;
        engMark[2] = 34;
        engMark[3] = 42;
        engMark[4] = 71;
        engMark[5] = 55;
        engMark[6] = 67;
        engMark[7] = 34;
        engMark[8] = 28;
        engMark[9] = 59;
        engMark[10] = 47;
        engMark[11] = 65;
        engMark[12] = 52;
        engMark[13] = 12;
        engMark[14] = 74;

        

        //English ID. Sample Data
        engId[0] = "E2003";
        engId[1] = "E2005";
        engId[2] = "E2001";
        engId[3] = "E2002";
        engId[4] = "E2006";
        engId[5] = "E2000";
        engId[6] = "E2004";
        engId[7] = "E2008";
        engId[8] = "E2007";
        engId[9] = "E2010";
        engId[10] = "E2009";
        engId[11] = "E2012";
        engId[12] = "E2011";
        engId[13] = "E2013";
        engId[14] = "E2014";
        
    } 

    //================================================== ========
    //
    // NAME : Menu
    // RETURN TYPE : none
    // PARAMETERS : none
    // DESCRIPTION : Menu for user to pick options          
    // 
    //
    // //================================================== ========
    static void menu()
    {
        System.out.println("\n\n\tXXXXXXXXXXXXXXXXXXXXXXXX XXXXX");
        System.out.println("\tX STUDENT RECORDS MAIN MENU X");
        System.out.println("\tXXXXXXXXXXXXXXXXXXXXXXXXXXXX X");
        System.out.println("\n\n1. - All Mathematics students");
        System.out.println("\n2. - All English students sorted by Student Id");
        System.out.println("\n3. - display English Merit students");
        System.out.println("\n4. - display the average examination marks");
        System.out.println("\n5. - All students above the Mathematics average");
        System.out.println("\n6. - EXIT");
    } 

    //================================================== ========
    //
    // NAME : displayStudents
    // RETURN TYPE : none
    // PARAMETERS : studentId 
    //      studentMark : Test score
    //      size : Array length
    //      upperLimitMark : upper inclusion mark in display
    //      lowerLimitMark : lower inclusion mark in display
    //      category : displays the category of display
    // DESCRIPTION : displays all students by Id alongside
    // their corresponding exam marks, as well as
    // identifying the group being displayed.
    //
    // //================================================== ========
    static void displayStudents(String[] studentId, int[] studentMark, int size, int upperMark, int lowerMark, String category)
    {
        //Command for system to print out title
        System.out.println("\n " + category + "\n");
        System.out.println("Student Identity\t Student");
        System.out.println(" Number\t\tExam Mark\n");

        //Start of loop
        for (int count = 0; count <= size - 1; count++)
        {
            if (studentMark[count] >= lowerMark && studentMark[count] < upperMark)
            {
                System.out.println(" " + studentId[count] + "\t\t " + studentMark[count]);
            } 

        } //End of loop

    } 

    //================================================== ========
    //
    // NAME : sortStudents
    // RETURN TYPE : none
    // PARAMETERS : studentId : maths student's  Id 
    // studentMark : maths student's test score
    // size : size of the array
    // DESCRIPTION : Sorts students in ascending order of student Id
    //
    // //================================================== ========
    static void sortStudents(String[] studentId, int[] studentMark, int size)
    {
       //Start Loop
        for (int count = 0; count < size - 2; count++)
        {
            
            for (int index = (count + 1); index < size - 1; index++)
            {
                //Use if statement to compare, and swap student Ids if required
                if (studentId[count].compareTo(studentId[index]) > 0)
                {
                    String tempId = studentId[count];
                    studentId[count] = studentId[index];
                    studentId[index] = tempId;
                } 
            } 
        } //End of loop
    } 

    //================================================== ======== //
    // NAME : averageResult
    // RETURN TYPE : double
    // PARAMETERS : studentId : maths student's unique Id 
    // studentMark: maths student's test score
    // size : size of the array
    // dESCRIPTION : Displays average student marks. 
    //
    // //================================================== ========
    static double averageResult(int[] studentMark, int size)
    {
        //declare variables
        double totalMark = 0, averageMark = 0;

        //Start of loop
        for (int count = 0; count <= size - 1; count++)
        {
            totalMark = studentMark[count] + totalMark;
        } //End of loop
        averageMark = totalMark / size;
        return averageMark;
    } 

    //================================================== ========
    // NAME : main
    // RETURN TYPE : none
    // PARAMETERS : args : [DEFAULT]
    // DESCRIPTION : Menu so user can pick what function they want 
    // program to proform.
    //================================================== ========
    public static void main(String[] args)
    {
        //Declare array
        int[] mathExamMark = new int[12];
        int[] engExamMark = new int[15];
        String[] mathStudentId = new String[12];
        String[] engStudentId = new String[15];

        //Initialise Array
        initialiseArrays(mathExamMark, engExamMark, mathStudentId, engStudentId);

        //Declare variables
        int menuOption = 0;
        boolean menuExit = false;
        int mathArraySize = mathStudentId.length;
        int englishArraySize = engStudentId.length;

        while (menuExit != true)
        {
            menu();

            
            System.out.println("\n\nPlease select a menu option number to continue.");
            menuOption = InOut.readInt();

           
            while (menuOption < 1 || menuOption > 6)
            {
                System.out.println("\n\n++++++++++++++++++++++++++ +++++++++++++++++++++++++++++");
                System.out.println("+ INVALID! - selection should be in the range 1 - 6! +");
                System.out.println("++++++++++++++++++++++++++++++ +++++++++++++++++++++++++\n");
                menu();
                System.out.println("\nPlease select a menu option number to continue.");
                menuOption = InOut.readInt();
            } 

            switch (menuOption)
            {
                    case 1:
                    displayStudents(mathStudentId, mathExamMark, mathArraySize, 100, 1, "All Maths students\n");
                    break;
                    case 2:
                    sortStudents(engStudentId, engExamMark, englishArraySize);
                    displayStudents(engStudentId, engExamMark, englishArraySize, 100, 1, "English students in Ascending order\n");
                    break;
                    case 3:
                    displayStudents(engStudentId, engExamMark, englishArraySize, 100, 55, "English Merit students\n ");
                    break;
                    case 4:
                    averageResult(mathExamMark, mathArraySize);
                    System.out.println("\nThe Maths average is " + averageResult(mathExamMark, mathArraySize));
                    averageResult(engExamMark, englishArraySize);
                    System.out.println("\nThe English average is " + averageResult(engExamMark, englishArraySize));
                    break;
                    case 5:
                    averageResult(mathExamMark, mathArraySize);
                    displayStudents(mathStudentId, mathExamMark, mathArraySize, 100,(int) averageResult(mathExamMark, mathArraySize) + 1, "Mathematics students above the average\n **************************************");
                    break;
               
                    case 6:
                    menuExit = true;
                    System.exit(0);
            } 
        } 
    }//End of main() method
}

Any help would be appricated
 
Would be more helpful if you told us exactly what is going wrong and only posting the code relevant to the problem.
 
Hi,

From what I remember objects in a collection can be sorted in different ways using comparators. It might be easier to do things this way rather than try to use loops etc.

The class that is used to form the sorted objects implements the comparable interface. Any number of comparators are then written (implementing the comparator interface). Each comparator has a compare method that takes arguments of two objects:

int compare(obj1, obj2);

The method returns 0 if the two objects are equal, -1 if o1 is less than o2, and 1 if o1 is greater than o2. How this value is arrived at is dependent on code in the compare method.

The Arrays.sort method can then be used to sort, passing in the required comparator class to sort the objects into different orders.

To put this into your code I think you'd need to rework your arrays so that each was composed of objects of a class that had attributes of mark and id (rather than hold each attribute in a separate array). For example:

Code:
public class studentmark implements Comparable {
    private int mark;
    private String id;

    public studentmark(int m, String i) {
        mark = m;
        id = i;
    }

    // Put the compareTo method in here.

    //Getters + setters in here.
}

You would then define an array or collection of marks e.g

Code:
studentmark[] mathmarks = studentmark[5];
mathmarks[0] = new studentmark(75,"M0001");
mathmarks[1] = new studentmark(80,"M0002");

You would then write two comparators, one to compare two studentmark objects by ID, and the other to compare two studentmark objects by mark. For example, a comparator to compare by mark:

Code:
public class comparebymark implements Comparator {
    public int compare(Object m1, Object m2) {
        studentmark mark1 = (studentmark)m1;
        studentmark mark2 = (studentmark)m2;

       if (mark1.getMark() < mark2.getMark())
           return -1;

       if (mark1.getMark() > martk2.getMark())
           return 1;

       return 0;
    }
}

The array could then be sorted by doing something like:

Code:
Arrays.sort(mathmarks, new comparebymark());

I think that's basically right, it's been a while since I did this. Hope it's of some help.

Jim
 
Lol thats just cofused me even more.

Here is the test data Im using.

Maths Examination

Student ID Mark
M1005"; 72
"M1002"; 84
"M1000"; 21
"M1003"; 48
"M1001"; 55
"M1004"; 49
"M1006"; 78
"M1010"; 21
"M1009"; 35
"M1008"; 98
"M1007"; 44
"M1011"; 56

English Exam
Student ID Mark
"E2003"; 82
"E2005"; 56
"E2001"; 34
"E2002"; 42
"E2006"; 71
"E2000"; 55
"E2004"; 67
"E2008"; 34
"E2007"; 28
"E2010"; 59
"E2009"; 47
"E2012"; 65
"E2011"; 52
"E2013"; 12
"E2014"; 74

So I need the program to link these results and put them in ascending by the student ID. So it would be

E2001 34
E2002 42

And so on.
 
Hi,

By using the single class with attributes to hold the mark and ID you are linking the two items of data together into one unit. Then, rather than hold separate arrays of the ID and mark you only need to hold one array of the class you've created. The two elements of data are then two parts of the same thing rather than just being linked by being like-numbered elements of different arrays. If a piece of code uses an object of this class then you'll know it's got hold of the ID and mark and that the two belong to each other - and that the two items of data will never become separated from each other.

Taking the studentmark class in my previous post you could have one array of the class for the maths results, another array of the class for the english results etc. Or, if you wanted to combine the marks from all subjects, you could add a subject attribute to the studentmark class and hold all the studentmark objects for all subjects in a single array

To put the results in order of the student id you'll need a comparator that will compare two studentmark objects by ID. In the compare method you'll pass in two objects. These will then be cast from the Object class to the studentmark class (so you'll see them as student mark objects) and you'll then compare their IDs returning -1,0 or 1 as appropriate. Somthing like:

Code:
public class comparebyid implements Comparator {
    public int compare(Object m1, Object m2) {
        studentmark mark1 = (studentmark)m1;
        studentmark mark2 = (studentmark)m2;

       if (mark1.getId() < mark2.getId())
           return -1;

       if (mark1.getId() > martk2.getId())
           return 1;

       return 0;
    }
}

Note, in the above the getId method is a method on the studentmark class that will simply return the value of the attribute used to hold the ID (it can't be accessed directly as it's declared as private - at least it was in my previous code).

Once you have this any array of studentmark classes can be sorted by ID using the comparator. Just use the sort method on Arrays, passing in an instance of the comparator. You don't need to use loops or anything, it's all handled for you by the Java API :)

If you want to sort the array using a different comparison just write another comparator and sort by that. Or if you want to sort a different array e.g an array of English rather than Maths results then that's easy too.

There are some good articles and examples of sorting in Java on the Internet which explain things a lot better than I can do.

Hope that helps and doesn't confuse which is the last thing I'd want to do.

Jim
 
Thanks for your help mate but it seems they are looking me to do it using loops. Im not sure. So confused at the moment and its needs to be handed in tomorrow. And its the only part im stuck on.

Anyone else have any idea's?

Guys if anyone can sort this out and post the working code Ill drop you some paypal for a few drinks when I get paid on the 29th of this month. Getting desperate at the moment. Need to hand it in tomorrow and dont want to have to quit the course over this stupid thing as as soon as we have handed this in thats the java part done.

Gareth
 
Last edited:
Edit - nm you are doing this.

Hang on, you want the id to increase and the marks to just correspond to the id ( so be in no particular order?). To do this the easies way is to do what your currently doing in the compare and swap but you prob need to convert the data into an integer so to compare E2001 and E2002 you need to cut off the E and convert the remaining string to an int. At least thats how id do it in c++ for an easy sort :)
 
Last edited:
Nah I want the IDs and Marks to correspond and then the whole lot be sorted by the ID so it will output...

E2001 34
E2002 42
E2003 82

And so on. THe id's in order with the correct marks corresponding with them. I only need this working for the english marks.

That does make sense doesnt it.

At the moment the program is just sorting the ID's and the corresponing marks arnt beside them in the output window.
 
Code:
String tempId = studentId[count];
int tempMark = studentMark[count];
studentId[count] = studentId[index];
studentMark[count] = studentMark[index];
studentId[index] = tempId;
studentMark[index] = tempMark;

would that not do what you wanted?
 
You should do a simple fixed-space sort, simplest one you can do is a bubble sort, it has rubbish efficiency, but it can be done in about 10 lines of code, plus it has a "swap" function that you can write to operate on both of the arrays at the same time:

http://en.wikipedia.org/wiki/Bubble_sort

The section marked pseudo code should practically give you the algorithm:

Code:
procedure bubbleSort( A : list of sortable items ) defined as:
  for each i in 1 to length(A) do:
     for each j in length(A) downto i + 1 do:
       if A[ j -1  ] > A[ j ] then
         swap( A[ j - 1],  A[ j ] )
       end if
     end for
  end for
end procedure

is prolly the most java-like and easiest to code. To do the swap function you simple take one of the 2 indexs out of the array, store it to a temp var, move the other index into that index and then move the temp var into the one you just moved from. Do the same to the marks array with the same indexes so it sorts at the same time.

Does that help?

There are tons of sorting algorithms such as heap sort, quick sort, merge sort, tree sort etc, but bubble sort will be the easiest to code for your purposes, normally you'd use a merge or quick sort as they have the best efficiency, but are prolly more complex for you to understand.
 
For a night class in Java this code seems to be a very strange way of teaching you Java. You nearly never have to use code like this in the real world because there are much better ways of doing this, I did do array sorting at Uni when we learnt Java but we were taught about all of the sorting algorithms such as selection sort, insertion sort, bubble sort, quick sort and merge sort.

It looks to me like you need to sort one array whilst also using the same sorting order to sort the second array so that they will match up. In the real world a collection of objects would be used to do this which makes it so much easier.
 
For a night class in Java this code seems to be a very strange way of teaching you Java. You nearly never have to use code like this in the real world because there are much better ways of doing this, I did do array sorting at Uni when we learnt Java but we were taught about all of the sorting algorithms such as selection sort, insertion sort, bubble sort, quick sort and merge sort.

It looks to me like you need to sort one array whilst also using the same sorting order to sort the second array so that they will match up. In the real world a collection of objects would be used to do this which makes it so much easier.

That could be true. Sitting here completly lost at the moment. And if i dont have the code working by 4.30 I will fail so no point going to class feel like throwing in the towel. :(

Anyone fancy booting up netbeans and trying toi get this stupid thing working?
 
I just realised you are already doing a bubble sort, what exactly is the problem here? If you need to sort the marks along side the students, you're practically there, I'll add the bit to you're code to demonstrate (it's not the way I'd have done it, but you don't seem to be allowed to use collections etc, also you don't really need to pass "size" but I'll keep it there to make it easier to understand):

Code:
    static void sortStudents(String[] studentId, int[] studentMark, int size)
    {
       //Start Loop
        for (int count = 0; count < size - 2; count++)
        {
            
            for (int index = (count + 1); index < size - 1; index++)
            {
                //Use if statement to compare, and swap student Ids if required
                if (studentId[count].compareTo(studentId[index]) > 0)
                {
                    String tempId = studentId[count];
                    studentId[count] = studentId[index];
                    studentId[index] = tempId;

                    // ADD THIS BIT TO SORT THE MARKS
                    int tempMark = studentMark[count];
                    studentMark[count] = studentMark[index];
                    studentMark[index] = tempMark;
                } 
            } 
        } //End of loop
    }

This would be so much easier using a more object oriented style of programming, really all you should need to do is use a collection such as a TreeMap<String, Integer> which would map student IDs to marks and auto sort them.
 
Last edited:
I just realised you are already doing a bubble sort, what exactly is the problem here? If you need to sort the marks along side the students, you're practically there, I'll add the bit to you're code to demonstrate (it's not the way I'd have done it, but you don't seem to be allowed to use collections etc, also you don't really need to pass "size" but I'll keep it there to make it easier to understand):

Code:
    static void sortStudents(String[] studentId, int[] studentMark, int size)
    {
       //Start Loop
        for (int count = 0; count < size - 2; count++)
        {
            
            for (int index = (count + 1); index < size - 1; index++)
            {
                //Use if statement to compare, and swap student Ids if required
                if (studentId[count].compareTo(studentId[index]) > 0)
                {
                    String tempId = studentId[count];
                    studentId[count] = studentId[index];
                    studentId[index] = tempId;

                    // ADD THIS BIT TO SORT THE MARKS
                    int tempMark = studentMark[count];
                    studentMark[count] = studentMark[index];
                    studentMark[index] = tempMark;
                } 
            } 
        } //End of loop
    }

This would be so much easier using a more object oriented style of programming, really all you should need to do is use a collection such as a TreeMap<String, Integer> which would map student IDs to marks and auto sort them.

God I love you. I could kiss you right now. :D Thank you very much thank you thank you thank you.

You have saved mny skin.

Mate will you drop me your paypal address and ill drop you money for a few pints when I get paid on the 29th of this month as the way of thanks

Gareth
 
God I love you. I could kiss you right now. :D Thank you very much thank you thank you thank you.

You have saved mny skin.

Mate will you drop me your paypal address and ill drop you money for a few pints when I get paid on the 29th of this month as the way of thanks

Gareth

You're welcome, and that won't be necessary :P. You pretty much had the problem done your self, you had just forgotten to sort the marks array at the same time, even though you had passed it as a parameter.
 
Back
Top Bottom