Sorting a string array and a int array - java

I am practicing sorting of arrays, and I have successfully sorted a string array.
My little program allows users to enter first number of students, then the name of each one, and at last their grade of each one.
But I also want to sort the int studentGrade array so that the grades in the printout matches the student. Here I am really stuck. See further down for more explanation down in the method: public void sortingAlgorithm
package assignment8exam;
import java.util.Scanner;
import java.util.Arrays;
/**
*
* #author Anders
*/
public class Course {
Scanner sc = new Scanner(System.in);
public void MainMenu() {
System.out.println("Enter data about a student, start by entering how many");
int numbers = sc.nextInt();// amount of student
String studentNames[] = new String[numbers];
int studentGrade[] = new int[numbers];
for (int i = 0; i < numbers; i++) {
System.out.println("Enter name of student");
Scanner name = new Scanner(System.in);
String names = name.nextLine();
studentNames[i] = names;
}
for (int j = 0; j < numbers; j++) {
System.out.println("Enter grade of student");
Scanner gradeSc = new Scanner(System.in);
int grade = gradeSc.nextInt();
studentGrade[j] = grade;
}
sortingArray(studentNames);
System.out.println("------------------------------------\n");
sortAlgorithm(studentNames, studentGrade);
System.out.println("What do you want");
System.out.println("Exit application 1");
System.out.println("Print out all names of the students 2");
System.out.println("Print out all the grades of the students 3");
System.out.println("Print out pairs consisting of “name­grade 4");
System.out.println("Search for a student - 5");
Scanner choice = new Scanner(System.in);
int order = choice.nextInt();
switch (order) {
case 1:
System.exit(1);
case 2:
PrintOutNames(numbers, studentNames);
case 3:
PrintOutGrades(numbers, studentGrade);
case 4:
PrintOutAll(numbers, studentGrade, studentNames);
case 5:
search(numbers, studentGrade, studentNames);
}
}
public static void PrintOutNames(int numbers, String studentNames[]) {
for (int i = 0; i < numbers; i++) {
System.out.println(studentNames[i]);
}
}
public static void PrintOutGrades(int numbers, int studentGrade[]) {
for (int i = 0; i < numbers; i++) {
System.out.println(studentGrade[i]);
}
}
public static void PrintOutAll(int numbers, int studentGrade[], String studentNames[]) {
System.out.println("--------------------------------------------------------\n");
for (int i = 0; i < numbers; i++) {
System.out.println("Name----> " + studentNames[i] + " grade ---> " + studentGrade[i]);
}
}
public static void search(int numbers, int studentGrade[], String studentNames[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter name on student you want to search on ");
String search = sc.nextLine();
for (int i = 0; i < numbers; i++) {
if (search.equals(studentNames[i])) {
System.out.println("Yes we have a student named " + studentNames[i] + " with the Grade " + studentGrade[i] + " \n ");
}
}
}
public static void sortingArray(String studentNames[]) {
Arrays.sort(studentNames);
System.out.println("-------------\n" + Arrays.toString(studentNames));
}
public static void sortAlgorithm(String studentNames[], int studentGrade[]) {
boolean flag = true;
while (flag) {
flag = false;
for (int j = 0; j < studentNames.length - 1; j++) {
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
// Here i want to place another array that sorts the grade?? how do i do that?
}
}
System.out.println(Arrays.toString(studentNames));
System.out.println(Arrays.toString(studentGrade));
}
}
}
}

The problem with your approach is that there is no relation between a student name and grade. If you sort the names and sort the grades you will end up with students with letter A having the least grades.
If that's a java assignment the best way to do it would be to create a data structure (class) called Student that has name and grade.
class Student{
String name;
int grade;
}
Then you will not have two arrays one with names and other with grades but just one array of Students and you will be able to sort that array by grades,names etc.
If you want a quicker solution that would be to use a map like Map<String,Integer> that will contain the grade for each student.
If you want to use multiple array you can make the sortAlgorithm method to swap the same indexes in both arrays (not only in the names array) and this way you will end up with grades sorted by names. This is the worst approach IMO because you depend too much on the array indexes instead of having some relation between the objects.

In this particular case, the solution is relatively easy. In this place, where you exchange the two student names:
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
}
}
You also exchange the corresponding grades at the same time:
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
int tempGrade = studentGrades[j];
studentGrades[j] = studentGrades[i];
studentGrades[i] = tempGrade;
}
}
So, whenever you do a switch of two student names, you switch the corresponding grades at the same time. This will keep the two arrays synchronized.
But as everybody else has been recommending, the better way is to create a class that represents a student - both name and grade. Why? Because in a real world case, a student may have other data, such as different subjects and their matching grades, an attendance record, contact information, whatever the university needs.
And having to add that to the loop for each such data item will make it intractable. If you have all the information in one record, you can just exchange record references, and then the whole data is exchanged together.
The basis for this is a class like:
class Student implements Comparable<Student> {
private String name;
private int grade = 0;
public Student( String name ) {
this.name = name;
}
public void setGrade( int grade ) {
this.grade = grade;
}
// In addition, you'll have getName(), getGrade(),
// and possibly a good `toString()` for printing a
// student record.
#Override
public int compareTo( Student otherStudent ) {
return this.name.compareTo( otherStudent.name );
}
}
Now you can define an array such as:
Student[] students = new Students[numbers];
And you can sort it directly with Arrays.sort() because Student implements Comparable, or you can do your own sorting algorithm and use the compareTo method. Your loop would be:
for (int i = j + 1; i < students.length; i++) {
if (students[i].compareTo(students[j]) < 0) {
Student temp = students[j];
students[j] = students[i];
students[i] = temp;
}
}

As noted above, the "correct" solution is probably to create a Student object and have it contain the student's name and grade. However, if you really need to have two separate arrays, you could just perform the same swapping on on the grade array that you do on the name array:
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
int tempGrade = studentGrade[i];
studentGrade[j] = studentGrade[i];
studentGrade[i] = tempGrade;
}

What you want to do, is Sort the grade array according to the student array i think, so in you for loop, everytime you switch a student, you want to switch the grade
for (int j = 0; j < studentNames.length - 1; j++) {
for (int i = j + 1; i < studentNames.length; i++) {
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String temp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = temp;
// Here i want to place another array that sorts the grade?? how do i do that?
int tempGrade = studentGrades[j];
studentGrades[j] = studentGrades[i]
studentGrades[i] = temp
}
}
System.out.println(Arrays.toString(studentNames));
System.out.println(Arrays.toString(studentGrade));
}
this design isn't that good, maybe take the advice from #Veselin Davidov in account

Your problem is that when you sort one array (say your student name list), your second array cant keep up with the same way.... apples and oranges.
You have somes solutions. The one that comes in mind right now is to use a map linking each name to its grade. You could also, well, use POO and declare a Studen object, that actually would look like a nicer solution, i'll let you read on Veselin's answer for that.
Let's look at the quickfix though, since i think that's why you're looking for :
Personally one workaround to your kinda-broken code would be to change your swap function to this :
if (studentNames[i].compareTo(studentNames[j]) < 0) {
String tmp = studentNames[j];
studentNames[j] = studentNames[i];
studentNames[i] = tmp;
int tmpGrade = studentGrade[i];
studentGrade[j] = studentGrade[i];
studentGrade[i] = tmpGrade;
}
But, i strongly recommend using either classes or a map.

You should really have an abstraction representing a Student, e.g.
public class Student {
Integer grade;
String name;
// getters and setters omitted
}
Then, you'll face the problem of extending the Comparator interface multiple times with different types (Integer and String). At this point, read this :
Using Comparable for multiple dynamic fields of VO in java

Related

Setter sets value for every object in class

I have a program that takes students' names and grades as user input and then performs some operations on them, which are irrelevant for the scope of the question. The code is as follows:
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Student {
// Four attributes that define Student
private String name;
private double points;
private int startYear;
private int[] grades;
public Student(String name, double points, int startYear, int[] grades) {
this.name = name;
this.points = points;
this.startYear = startYear;
this.grades = grades;
}
//Constructor. Everyone starts with 0 points and this year
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); //Create scanner
System.out.println("Please enter the number of students:");
int count = sc.nextInt(); // Number of students
System.out.println("Please enter the number of grades:");
int count1 = sc.nextInt(); // Number of grades
Student students[] = new Student[count]; // Create array of student objects based on previously entered value
int[] temp = new int[count1]; // Temporary array for storing grades entered
for (int i = 1; i < count + 1; i++) {
System.out.println("Please enter the name of student " + i);
String name = sc.next();
students[i - 1] = new Student(name,0.0,2018,temp); // Creating student object
System.out.println("Please enter grades of " + name);
for (int k = 0; k < count1; k++) {
int personal_grades = sc.nextInt();
temp[k] = personal_grades; //filling the temporary array
//System.out.println(grades.length); //for debugging
}
students[i - 1].setGrades(temp); //transferring from temporary array to student object array
students[i-1].printGrades();
}
System.out.println((students[0].name));
System.out.println((students[1].name));
System.out.println(Arrays.toString(students[0].grades));
System.out.println(Arrays.toString(students[1].grades));
for(int i = 0; i < count; i++) {
System.out.println("Grades of " + students[i].name + " are:");
//students[i].printGrades();
}
for(int i = 0; i < count; i++) {
System.out.println("Average of " + students[i].name + " is:");
// students[i].average();
}
int passed=0;
for(int i = 0; i < count; i++) {
if(students[i].average()>5.5)
{
passed++;
}
}
System.out.println(passed+" students passed!");
}
public void setGrades(int[] temp) {
this.grades = temp;
}
public int[] getGrades() {
return grades;
}
public void printGrades() {
System.out.println(Arrays.toString(grades));
}
public float average (){
int k = 0;
int sum=0;
float average=0;
while (k < this.grades.length) {
sum=sum+this.grades[k];
k++;
}
average = sum/(float)this.grades.length;
System.out.println(average);
return average;
}
}
The problem I am having with the code is as follows: the setter method appears to set the values for all of the objects that were ever created. Take this test run as an example:
You can see that the grades for the last student entered appear in every student's record. I have debugged and found that it is the setGrades method that causes this. However, I am using the this keyword - why does it set the value for all the objects then?
You need to move the
int[] temp = new int[count1]; // Temporary array for storing grades entered
inside the outer for loop, otherwise all created Students will have a reference to same grades array and all will end up with the grades of the last student.
It's because you are using the same array for all the grades of everyone.
Moving
temp = new int[count1]; inside the first loop should fix it
Note how both Student's constructor and Student::setGrades() get grades by reference.
This means that for each Student's instance, its grades field points to the parameter that was received during its initialization.
However, you only initialize temp once and therefore all the instances point to the same grades array. Once this array is changed, calling student.printGrades() will print the shared array's contents.
This can be solved by initializing temp on every iteration, before creating a new Student instance; Or by copying the array by value inside setGrades() method:
public void setGrades(int[] temp) {
this.grades.clone(temp);
}
Move the array (temp) holding the grades inside the loop where you create individual Students
for (int i = 1; i < count + 1; i++) {
...
int[] temp = new int[count1]; //The array holding the grades must be *specific* for each student
students[i - 1] = new Student(name, 0.0, 2018, temp); // Creating student object
...
students[i - 1].setGrades(temp); //transferring from temporary array to student object array
students[i - 1].printGrades();
}
In your original code, you are using just one array i.,e temp was pointing to the same array all the time. After you finish initializing the first Student, when you loop populating the grades for the second student, you are mutating (or modifying) the same grades array created for the first student.

Java Parallel arrays on finding two matching items

So in school, we just learned arrays and we have a project on it. It is to make a parallel arrays on a students name, test average score, quiz average score, homework average score, and final average score. Also, we have to find the highest and lowest scores. I have the highest score figured out unless 2 students score the same high school, then it will only show one. Here are my methods :
public String getHighestScore(){
double highScore = 0;
String students = "";
for(int i = 0; i < totalTests; i++){
if(quarterAverages[i] > highScore){
highScore = quarterAverages[i];
students = names[i];
}
}
return students;
}
This segment of code now works. I needed to make the greater than in the if statement a greater than or equal to and add name to the string instead of changing it to one name.
public String getHighestScore(){
double highScore = 0;
String students = "";
for(int i = 0; i <= totalTests; i++){
if(quarterAverages[i] >= highScore){
highScore = quarterAverages[i];
students += names[i] + " ";
}
}
return students;
}
This one only outputs 1 student with the high score rather than 2. My question is how can I output multiple students with the same highscore.
To return multiple names, you need to do a few things:
You should return a List<String> instead of a single String value. (Of course, the list will only have one element if there are no ties for the highest score.)
You need to check whether the ith score is tied with the current high score and add the name to the current list if it is.
When a new high score is detected, you need to clear the list of names (which are tied, but no longer the high score) and add the new high score name.
Something like this (untested) might do the trick:
public List<String> getHighestScore() {
double highScore = 0;
List<String> students = new ArrayList<>();
for(int i = 0; i < totalTests; i++){
if(quarterAverages[i] >= highScore){
if (quarterAverages[i] > highScore) {
highScore = quarterAverages[i];
students.clear();
}
students.add(names[i]);
}
}
return students;
}
EDIT: Since you are just learning about arrays, you may not know about Java's List data structure. Here's a variation that returns a concatenation of all the names, separated by a delimiter:
public String getHighestScore() {
double highScore = 0;
String students = "";
String delimiter = ", ";
for(int i = 0; i < totalTests; i++){
if(quarterAverages[i] >= highScore){
if (quarterAverages[i] > highScore) {
highScore = quarterAverages[i];
students = "";
} else if (students.length() > 0) {
students += delimiter;
}
students += names[i];
}
}
return students;
}
(This should, of course, be done with a StringBuilder, but I don't know that you've learned about that, either.)
P.S. Since this method returns the name(s) with the highest score, and not the highest score itself, I'd strongly suggest that you rename the method accordingly.
Buddy, given the amount of information and code you have provided, below is what best I can suggest. Idea to send a list of students instead of string containing one name.
public ArrayList<String> getHighestScore(){
double highScore = 0;
ArrayList<String> students = new ArrayList<String>();
for(int i = 0; i < totalTests; i++){
if(quarterAverages[i] > highScore){
highScore = quarterAverages[i];
students.add(names[i]);
}
}
return students;
}
Find the highest score first, then find the students who has the highest score.
public static String getHighestScore() {
// First get the highest score
double highScore = 0;
for (int i = 0; i < quarterAverages.length; i++) {
if (quarterAverages[i] > highScore) {
highScore = quarterAverages[i];
}
}
// Now get the students with the highest score
String students = "";
for (int i = 0; i < quarterAverages.length; i++) {
if (quarterAverages[i] == highScore) {
students += names[i] + ", ";
}
}
// Substring is to remove the ", " at the end. That's what the -2 does.
return students.substring(0, students.length() - 2);
}
EDIT
Or you could just use one loop
public static String getHighestScore() {
// First get the highest score
double highScore = 0;
String students = "";
for (int i = 0; i < quarterAverages.length; i++) {
if (quarterAverages[i] >= highScore) {
if (quarterAverages[i] > highScore) {
highScore = quarterAverages[i];
students = "";
}
students += names[i] + ", ";
}
}
// Substring is to remove the ", " at the end. That's what the -2 does.
return students.substring(0, students.length() - 2);
}
Data
private String[] names = { "Chris", "John", "Joe" };
private double[] quarterAverages = { 100.0, 100.0, 99.0 };
Result:
Chris, John
Alright so I will try my best to help you as far as I can with the information you gave us.
Considering it's a school assignement, I guess you have to return a String and aren't allowed to use Lists and so on.
Also I'm assuming the following:
The Array names contains the student names.
You want to get the names of the students with the highest scores in your String. If there are several students with the same score (which is the highest), all students should be included in that String
Let's look at your first code snippet (not my proposed solution)
public String getHighestScore(){
double highScore = 0;
String students = "";
for(int i = 0; i <= totalTests; i++){
if(quarterAverages[i] >= highScore){
highScore = quarterAverages[i];
students += names[i] + " ";
}
}
return students;
}
So let's say that now there is a student with the quaterAverage of 5 at Index 0 and a student with the quaterAverage of 6 at the Index 1.
Since you add something at the end of the String if the current quarter Average is higher, you would have the name of the student at index 0 (currently the highest score) and then the name of the student at index 1 (then the highest score). That isn't what you seem to be striiving for since you only want the names of the highest scoring people.
I would propose something like this:
public String getHighestScore(){
double highScore = -1; //maybe the highest score is 0
String students = "";
for(int i = 0; i <= totalTests; i++){
if(quarterAverages[i] > highScore){
highScore = quarterAverages[i];
students = names[i];
}
else if(quarterAverages[i] == highScore){
students += ", " + names[i];
}
}
return students;
}
So now, each time we find a student with the same score as the current highest one, we add the name to the String. If we find a new Highest score we reset the String and go from there.

Student scores sorting help needed for Java

import java.util.Scanner;
import java.util.Arrays;
class StudentScores {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the # of students");
int numOfStudents = input.nextInt();
int[] scores = new int[numOfStudents];
String[] names = new String[numOfStudents];
for (int i = 0; i < numOfStudents; i++) {
input.nextLine();
System.out.print("Enter name: ");
names[i] = input.nextLine();
System.out.print("Enter score: ");
scores[i] = input.nextInt();
}
// This doesn't sort anything, it just prints out the result in unsorted way
/*for (int i = 0; i < numOfStudents; i++) {
System.out.println(names[i] + " " + scores[i]);
}*/
Arrays.sort(scores);
reverse(scores);
for (int u: scores) {
System.out.println(u);
}
}
public static int[] reverse(int[] array) {
for (int i = 0, j = array.length - 1; i < j; i++, j--) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
}
The original question is:
Write a program that prompts the user to enter the number of students, the students’ names, and their scores, and prints student names in decreasing order of their scores.
My question is how do you display the name with the sorted list of scores?
You necessarily don't have to give me a complete solution, just give me a hint so I can solve it myself.
You can encapsulate the related fields into a class, e.g. a StudentRecord can encapsulate the fields name and score.
Now, you sort a collection of these objects based on the second field, score. When it comes time to print the sorted result, you iterate through the collection and print the first field, name.
To illustrate:
public class StudentRecord implements Comparable<StudentRecord> {
private String name;
private int score;
public StudentRecord(String name, int score) {
this.name = name;
this.score = score;
}
#Override
public int compareTo(StudentRecord other) {
if (score == other.score) return 0;
else if (score < other.score) return -1;
else return 1;
}
#Override
public String toString() {
return name;
}
public static void main(String[] args) {
StudentRecord stu1 = new StudentRecord("Matt", 50);
StudentRecord stu2 = new StudentRecord("John", 90);
if (stu1.compareTo(stu2) == 0) {
System.out.println(stu1.toString() + " has the same score with " + stu2.toString());
}
else if (stu1.compareTo(stu2) < 0) {
System.out.println(stu1.toString() + " has a lower score than " + stu2.toString());
}
else {
System.out.println(stu1.toString() + " has a higher score than " + stu2.toString());
}
// output:
// Matt has a lower score than John
}
}
In many sorting algorithms, implementing the Comparable interface gives the algorithm enough information to sort a collection of such objects implementing said interface.
You're not going to be able to use Arrays.sort() for this problem because you need to sort both arrays together. Write a sorting function that sorts the scores in order, and every time it swaps two scores, swap the students with those scores as well.

Find and Print high number array method Java

What I’m attempting to do is search “gradePsd” array find the highest grade and if there are two grades that are the same value print the name (s) of the students to console.
The problem I’m having is that this method is taking the first index value of the array and printing it because it IS the high value at the first pass and if the second value is larger than the first then it will also print and so on.
So my question is how can I get it to just print the student (s) with the high grade.
public static void hiMarkMethod(String[] NamePsd, int[] gradePsd)
{
String nameRtn = "";
int num = gradePsd[0];
System.out.println ("\n\nThe Student(s) with Hightest Mark(s) are:");
for (int i = 0; i < gradePsd.length; i++)
{
if (gradePsd[i] >= num)
{
num = gradePsd[i];
nameRtn = NamePsd[i];
}
System.out.print(nameRtn + ", ");
}
}
first find the highest number
then print the students with that number
public static void hiMarkMethod(String[] NamePsd, int[] gradePsd)
{
String nameRtn = "";
int num = gradePsd[0];
System.out.println ("\n\nThe Student(s) with Hightest Mark(s) are:");
//find the highest number
for (int i = 0; i < gradePsd.length; i++){
if (gradePsd[i] >= num){
num = gradePsd[i];
}
//print students with that number
for (int j = 0; j < NamePsd.length; j++){
if (gradePsd[j] == num)
{
nameRtn = NamePsd[j];
System.out.print(nameRtn + ", ");
}
}
one of possible 1000 solutions.
Initialize num with -1 and take the System.out out of the for loop. But you can only determine one student with your code. You need nameRtn to be a Collection if you want to store more than one name.
Something like this:
public static void hiMarkMethod(String[] NamePsd, int[] gradePsd) {
Collection<String> namesRtn = new ArrayList<String>();
int num = -1;
for (int i = 0; i < gradePsd.length; i++) {
if (gradePsd[i] > num) {
num = gradePsd[i];
namesRtn.clear(); // clear name list as we have a new highest grade
namesRtn.add(NamePsd[i]); // store name in list
} else if (gradePsd[i] == num) {
namesRtn.add(NamePsd[i]); // if a second student has the same grade store it to the list
}
}
System.out.println ("\n\nThe Student(s) with Hightest Mark(s) are: " + namesRtn);
}

Sorting the two highest numbers in an array

I'm sorry to ask, but I'm having trouble with an exercise in my book, and I am unsure how to fix it. After entering the student's name and score, I am to find the highest and second highest score. However I cannot find a proper way to find the two highest scores.
The current way I use works, but fails the user enters scores from low to high, such as 70, 80, and 90. If done 90, 80, and 70, it sorts the numbers appropriately.
Is there anything I could change/do/read to put me on the right path?
import java.util.Scanner;
public class StudentSort {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// For finding highest scores with corresponding array
double firstHighest = 0;
int firstEntry = 0;
double secondHighest = 0;
int secondEntry = 0;
System.out.print("Enter the number of students: ");
int studentCount = input.nextInt();
// Length of arrays set
int[] studentScores = new int[studentCount];
String[] studentName = new String[studentCount];
// Go through loop to set scores and names of each student
for (int i = 0; i < studentCount; i++) {
System.out.print("Enter a student name: ");
studentName[i] = input.next();
System.out.print("Enter a student score: ");
studentScores[i] = input.nextInt();
}
// Find out the highest and second highest scores
// Problem with secondHighest/Entry
for (int i = 0; i < studentScores.length; i++) {
if (studentScores[i] > firstHighest) {
secondHighest = firstHighest;
firstHighest = studentScores[i];
firstEntry = i;
} else if (studentScores[i] > secondHighest) {
secondHighest = studentScores[i];
secondEntry = i;
}
}
System.out.println("Top two students: ");
System.out.println(studentName[firstEntry] + "'s score is " + firstHighest);
System.out.println(studentName[secondEntry] + "'s score is " + secondHighest);
}
}
As always, I thank you for any help that you can provide.
It looks like you just forgot to update secondEntry when you get a new highest score. Before the line:
firstEntry = i;
Try adding:
secondEntry = firstEntry;
The problem is here
if (studentScores[i] > firstHighest) {
secondHighest = firstHighest;
firstHighest = studentScores[i];
firstEntry = i;
}
you successfully update the values for both secondHighest and firstHighest but you don't fix secondEntry;
you need to add
secondEntry = firstEntry;
before
firstEntry = i;
There are more than 1 ways to solve this problem. The most intuitive way would be akin to picking up a hand of cards (i.e insertion sort). Think of the inputs as a continuous list of cards. It doesn't really matter what order they come in as most players will sort them going from lowest to highest (or the other way around).
So in your input loop:
while(...some_condition_that_ensures_more_input){
//this can be a list for instance, which you keep in order
list = insert_into_correct_place(input);
}
/**
Assuming
a)you sort from lowest to highest
b)there is more than 1 input entered):
*/
highest = list.get(list.length()-1)
second_highest = list.get(list.length()-2)
Another intuitive way (and actually faster) way is to just keep track of two variables:
int [] highest = {Integer.MIN_VALUE(), Integer.MIN_VALUE()};
while(...){
highest = replace_lowest(input, highest);
}
/**
* arr is sorted from lowest to highest : arr[0] is always <= arr[1]
*/
int [] replace_lowest(int input, int [] arr){
//Case 0 : input is less than both the highest 2 numbers
// or is equal to one of them
if (input < arr[0] || input == arr[0] || input == arr[1]) { return arr; }
//Case 1 : input is greater than one of the highest 2, but not both
if (input > arr[0] && input < arr[1]) { arr[0] = input; return arr; }
//Case 2 : input is greater than both of the highest 2 numbers
second_highest = arr[1]; arr[0] = arr[1]; arr[1] = input;
return arr;
}
The first approach is a bit more flexible (it would allow you to pick out X highest numbers instead of just two). The second approach is faster if you know that you will never have to readjust the number of output variables.
You can simply use the java.util.Arrays class and its sort() method. Here's what the code might look like:
Arrays.sort(studentScores);
int firstHighest = studentScores[studentScores.length - 1];
int secondHighest = studentScores[studentScores.length - 2];
Hope this helps.
I wrote you a method with the help of an inner class; it returns an array, the first element is the Student with the heighest score, the second Student the one with the second score.
import java.util.Arrays;
import java.util.Comparator;
public class StudentSort {
static class Student {
Student(int score, String name) {
this.score = score;
this.name = name;
}
int score;
String name;
}
private static Student[] test(int[] studentScores, String[] studentNames) {
Student[] students = new Student[studentScores.length];
for(int i = 0; i < studentScores.length; i++) {
students[i] = new Student(studentScores[i], studentNames[i]);
}
Arrays.sort(students, new Comparator<Student>() {
#Override
public int compare(Student o1, Student o2) {
return new Integer(o1.score).compareTo(o2.score);
}
});
return new Student[]{students[0], students[1]};
}
public static void main(String[] args) {
int[] studentScores = new int[] {5, 9, 7};
String[] studentNames = new String[]{"Jan", "Bert", "Piet"};
Student[] students = test(studentScores, studentNames);
System.out.println("heighest: " + students[0].name + ": " + students[0].score);
System.out.println("second: " + students[1].name + ": " + students[1].score);
}
}

Categories

Resources