I am currently working on a project for school and am really struggling. I am supposed to selection sort a group of Student objects and then display them in selection sort order.
Create an array with the size of 10 and assign student details (Name, BroncoId, age and TotalMarks) to the array. Perform the selection sort to sort the students in descending order based on their total marks.
a. Steps:
i. Create the student list (use Random class in java to generate the age (15-25) and total (0-100))
ii. Print the Student List in a table format
iii. Perform selection sort based on the total marks of the students
The place I am stuck at currently is making the selection sort. I understand how to create the selection sort, but I can't seem to translate it for this implementation.
My selection sort code:
public static Student[] selectionSort(Student[] studentList)
{
for(int i = 0; i <studentList.length-1; i++)
{
int minIndex = studentList[i].getGrades();
int pos = i;
for(int j = i + 1; j < studentList.length-2; j++)
{
if(studentList[j].getGrades() > studentList[minIndex].getGrades())
{
minIndex = studentList[j].getGrades();
pos = j;
}
}
int temp = studentList[pos].getGrades();
studentList[pos] = studentList[i];
int k = studentList[i].getGrades();
k = temp;
}
return studentList;
}
When I run this code, the console returns:
I sought tutoring to hopefully fix this problem, but my tutor gave me a few nonfunctional suggestions. We were both stumped at the end of the session.
My code for printing:
public static void printStudentInfo(Student[] students)
{
System.out.println("Name: AGE: idNumber: Score:");
for(Student student: students)
{
if(student.getName().length() <= 49)
System.out.printf("%-50s %-5d %-10s %-4d\n", student.getName(), student.getAge(), student.getID(), student.getGrades() );
else
{
System.out.printf("%-50s %-5d %-10s %-4d\n", student.getName().substring(0,48), student.getAge(), student.getID(), student.getGrades() );
System.out.println();
int i = 0;
while(i <= student.getName().length())
{
System.out.printf("%-50s", student.getName().substring(49 +48*i, 97+48*i) );
System.out.println();
i++;
}
}
}
}
As more of an issue out of passion, I sought to make an interesting print method. My problem is, also that I don't really know how to parse and format a string of 155 characters for instance. What do I put in this while lop to accomplish this?
I want the program to output one object name line like:
49 characters
49 chars
…
What ever is left
It probably won't ever go past three lines, but hey, who says I can't give an example like that? What do I put in the header of the while loop to accomplish this?
PS:
Here is the Student class if you need it.
public class Student
{
private String name;
private int age;
private String idNumber;
private int gradePoints;
public Student(String name, int age, String idNumber, int gradePoints)
{
this.name = name;
this.age = age;
this.idNumber = idNumber;
this.gradePoints = gradePoints;
}
public void setName(String name)
{
this.name = name;
}
public void setAge(int age)
{
this.age = age;
}
public void setidNumber(String idNumber)
{
this.idNumber = idNumber;
}
public void setPoints(int gradePoints)
{
this.gradePoints = gradePoints;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String getID()
{
return idNumber;
}
public int getGrades()
{
return gradePoints;
}
Welcome to SO Matthew.
Rather than giving you a solution I thought it might be useful to give you a process for solving the problem yourself.
Good practice in software development is to break your problem down into very small components, make sure each of those work perfectly (through unit testing) and then build your solution from those components.
In line with that practice I suggest you do the following:
list each of the individual steps required to do a selection sort on paper.
Pick the simplest one (e.g. swapping two elements).
Write a unit test that would pass if your swap method worked
run the unit test and verify that it fails
write the simplest code you can to make that test pass
write a new test to cover a more complex scenario that isn't yet supported
keep going until you believe that method works perfectly
move onto the next method
once all the components are working perfectly write the method that calls them all using the same process (i.e. test first then code)
If you follow this process then you will end up with a system that you understand perfectly, works, is maintainable, and that you can refactor. It has another very significant benefit: it means when you come to SO with a question you'll be asking about a specific item that you don't know how to solve rather than a 'why doesn't my code work' question. Specific questions tend to get better and faster responses.
In your case, I would start with methods for swapping items (hint: your code for this doesn't work which you'll discover quickly when you write a unit test) and then move on to finding the smallest item in a sublist. Then a method that uses those two to put the smallest item at the start of a sublist. Finally a method that performs that method for all sublist progressively. Make sure each method is working perfectly, including checking validity of arguments, before you move on to putting them together.
I am a Java beginner, I have been trying to read a csv file from my computer by using Java and insert the data into a ArrayList.
public class DataRepository {
public void loadFile(){
ArrayList<String> binsGrade = new ArrayList<String>();
try {
Scanner fileScanner = new Scanner(new File("C:\\Users\\Max\\Desktop\\Grade_SampleData.csv"));
while(fileScanner.hasNextLine()){
binsGrade.add(fileScanner.nextLine());
}
fileScanner.close();
System.out.println(binsGrade);
} catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
And below is the result I got:
[name,literature,math,physics,chemistry,biology,history,geology,art,sports, Michael,80,90,82,79,75,70,72,68,95, Amy,85,88,73,79,88,93,90,92,75, Johnson,72,89,81,84,83,72,89,90,82, Bob,80,81,84,89,87,90,71,65,89, Tommy,70,89,79,90,88,73,75,89,91, Rachel,90,91,80,92,87,92,95,97,87, Evonne,78,91,87,88,91,76,74,86,91]
All the records are in one row, but I actually want it to be in separated rows and columns, and for example, when I call name, I can get the value: Michael, Amy, Johson and etc. When I call literature, I can get 80, 85, 72, 80 and etc.Then I can probably use these data to do some calculation, like calculate the average, or get the maximum score and etc.
Although I have been searching online for a while, I still have not figured out the best way to achieve this. Can you please share your ideas if you have one minute? Your help will be really appreciated. Thanks!
If you want to have something implemented quickly, you can follow Srivenu comment and use a Map<String, List<String>>. Each entry of the Map will have the name as the key, and a list of string for all the results. For example to add Michael :
myMap.add("Michael", Arrays.asList({"20", "12", "8", "80"}));
Then create the different methods that will go through this map to compute the average, or find the max, etc
If you want a more oriented object approach I suggest you to create objects that will represent your data. First a result object that will contain two attributes, a string that will be the subject and an int that will be the score.
public class Result {
private String subject;
private int score;
public Result(String s, int i) {
subject = s;
score = i;
}
//Add Setters and Getters
//Add additional method if required
}
Secondly Have a Person object that wil represent someone. It will have two attributes, a String representing the name and a list of Results objects.
public class Person {
private String name;
private List<Result> results;
public Person(String s, List<Result> r) {
name = s;
results = r;
}
//Add getters and setters
//Add additional methods if required
/**
* Example of additional method
* This one will return the score for a given subject
**/
public int getScore(String subject) {
Result r = results.get(subject);
return r.getScore();
}
}
Thirdly, create a GroupOfPerson Class that will contain one attribute, a list of person. Then This class will have methods that will return the average, the max, etc...
public class GroupOfPerson {
private List<Person> persons;
public GroupOfPErson(List<Person> p) {
persons = p;
}
/**
* Example of method.
* This one will return the average score for the given subject
**/
public int getAverageForSubject(String subject) {
int average = 0;
for(Person p : persons) {
average += p.getScore(subject);
}
average /= persons.size();
return average;
}
//Add other methods
}
Finally when reading your CSV file, create the corresponding objects.
I have a question regarding the for-loop and ArrayList. I have a HashMap with String and Integers, where the String represents a class, and the Integer represents the grade. They I have a collection of students in an ArrayList. So what I am trying to do is find the average of the grades of the students in the ArrayList. This is the code of that class:
import java.util.ArrayList;
public class BachelorStudenter {
private ArrayList<BachelorStudent> bs;
public Bachelorstudenter() {
bs = new ArrayList<>();
}
public int bsGjennomsnitt() {
int sum = 0;
int gjennomsnitt = 0;
if(!bs.isEmpty()){
for(BachelorStudent b : bs.values){
sum += b.finnGjennomsnitt();
}
return gjennomsnitt;
}else {
return 6;
}
}
}
I know that the bs.values in the for-loop within the if-statement is wrong, but I've tried googling what I should use instead, and neither .contains or .size works.
Oh, and I also have another class called BachelorStudent, where I can create an object of the BachelorStudent and it will be put in the ArrayList in Bachelorstudenter.
Does anyone know what I need to put there instead?
If what you want to to is to return the average of the average grade over all the students you could do the following:
import java.util.ArrayList;
public class Bachelorstudenter {
private ArrayList<Bachelorstudent> bs;
public Bachelorstudenter() {
bs = new ArrayList<>();
}
public double bsGjennomsnitt() {
double sum = 0.0;
double gjennomsnitt = 6.0;
if(!bs.isEmpty()){
for(Bachelorstudent b : bs){
sum += b.finnGjennomsnitt();
}
gjennomsnitt = sum/bs.size()
}
return gjennomsnitt;
}
}
please note that I changed the return value, sum and gjennomsnitt to double as an average may also be a non-integer value.
The answer also assumes that the b.finnGjennomsnitt() returns the average over all classes a student attends and returns this. If you only want to return the average for all students in ONE class the answer will not give you this. Please specify in your question and also include the code for finnGjennomsnitt() if this is part of the question.
The method in the answer will return 6.0 as average if there are no students, as in the code in the question. Perhaps this should be reconsidered as it makes the case of an exceptional group of students with straight 6.0 grades equal to the case of no students. Perhaps you can return -1 when there are no students?
What you a doing is recursively ending in an exception....
You have to do::
for(Bachelorstudent b : bs){
sum += b.getSomething();
}
and define getSomething as a getter for a field in the classs Bachelorstudent
Hi and thanks for at least visiting.
I promise I've checked every question that's seemed relevant to what I need to do. I've tried every solution on the site and most on Google.
What I'm attempting to do is create a personality quiz that matches you to a certain trait. The desired program result is that the highest matched trait will display first. After the person tests, calculations are done to see what percentage a person is of each trait and that percentage is stored in doubles.
So I'm trying to order or sort an arraylist of objects based on this double. I've tried various strategies, but I'll give you the current two:
With Comparable
public static class results implements Comparable<results>
{
private double rPercent; //I've tried public and just leaving it double
public results(double percent)
{
this.rPercent = percent;
Percent*=100;
System.out.printf("You are %.2f," percent);
System.out.println();
}
public double getPercent()
{
return rPercent;
}
public int CompareTo(results Percent)
{
double p1 = (results Percent).getX();
double p2 = this.X - p1;
return (int)p2;
}
}
public static void main(String[] args) throws Exception
{
ArrayList<results> sortList = new ArrayList<results>();
sortList.add(new results(prcTrait1));
sortList.add(new results(prcTrait2));
sortList.add(new results(prcTrait3));
Collections.sort(sortList);
results beginResults = sortList.get(0);
results beginResults = sortList.get(1);
results beginResults = sortList.get(2);
//It prints out the traits in their original order. Always.
}
That's one solution I saw.
Then this is another thing I'm trying:
With Comparater
public class personalityQuiz
{
public double newPercent;
//. . .
public static class results
{
personalityQuiz v = new personalityQuiz();
//v for variable
//That and I wanted it to be short because I would be using it alot.
public results(double percent)
{
v.newPercent = percent;
percent*=100;
System.out.printf("You are %.2f", percent);
System.out.println();
}
}
public double getPercent
{
double xPercent = newPercent;
return xPercent;
}
public static void main(String[] args) throws Exception
{
ArrayList<results> sortList = new ArrayList<results>();
sortList.add(new results(prcTrait1));
sortList.add(new results(prcTrait2));
sortList.add(new results(prcTrait3));
Collections.sort(sortList, new Comparator<results>()
{
public int compare(results p1, results p2)
{
personalityQuiz v = new personalityQuiz();
double newP1 = p1.v.getPercent();
double newP2 = p2.v.getPercent();
if(newP1 < newP2)
{
return 1;
}
else if(newP2 < newP1)
{
return -1;
}
else
{
return 0;
}
});
results beginResults = sortList.get(0);
results beginResults = sortList.get(1);
results beginResults = sortList.get(2);
//still prints them in their original order
}
}
I apologize for the probable various mistakes in execution there.
I'm somewhat self-learning Java right now and what I know was basically self-taught as well.
Anyway, any help would be amazing.
And I'll try to be around to respond to any comments or answers quickly ^^~
In your first example, I think you missed a few things (and results should be Results, also CompareTo should be compareTo) -
public static class Results implements Comparable<Results>
{
private double rPercent; //I've tried public and just leaving it double
public Results(double percent)
{
this.rPercent = percent;
percent*=100;
System.out.printf("You are %.2f%n", percent);
}
public double getPercent()
{
return rPercent;
}
#Override
public int compareTo(Results result)
{
return new Double(getPercent()).compareTo(result.getPercent());
}
}
In your compare method, try Double.compare(double x, double y).
EDIT: Elliott Frisch expanded on that
I'm going to be honest and say some of your code was hard to follow, it would be beneficial for you to learn the 'standards' of the Java programming language, such as classes always starting with a capitol letter etc..
In your first example, the reason they were always coming out in the same order is probably because of a rounding error. When you're converting a double to a integer, it was most probably less than 1 (but greater than 0) in magnitude. Hence it was being rounded down (or up) to 0. Meaning that the collections API was not sorting them as there were being seen as 'equal'.
Your second example I was not able to follow, sorry.
-Thomas
Beforehand: This is a homework assignment so I need answers with explanations.
I am a first year student and my teacher is extremely vague while teaching so
I need some help understanding how to use the ArrayList in his instructions.
**I just need help understanding how this all works. I'm writing the code but I don't know how any of it works.
The Textual User Interface is supposed to be written in another class that I haven't done yet.**
My instructions were:
GradeManager Class
Start by developing a class to describe a GradeManager. Because this exercise is far more about writing an interactive application, we'll keep this class SIMPLE. Our GradeManager will just keep track of an ArrayList of scores and define the following methods:
A single constructor that accepts no parameters, but sets up the ArrayList so that it is
capable of holding some scores
A method called addScore that will accept a score and add it to the ArrayList
A method called getAverage that will return the average of all scores in the ArrayList
GradeTUI Class
This class will keep track of a GradeManager object as an instance variable. You will need to write a
constructor that accepts the GradeManager object that it will be using.
This class will also contain a method named run. This method will give the user the ability to either (1)
enter a score to be stored (in the GradeManager object) or (2) display the average of all scores entered
so far. Allow the user to continue this program by choosing one of these options until they are finished.
Driver Class
Once you are satisfied that these classes are defined and working properly, develop a driver class
containing a main method that will create an instance of GradeManager, pass this object to the
GradeTUI constructor, and then use the GradeTUI object to call run.
This is what I wrote:
public class GradeManager {
private ArrayList<Integer> gradeList;
public GradeManager() {
ArrayList<Integer> gradeList = new ArrayList<Integer>();
this.gradeList = gradeList;
}
public void addScore(int score) {
this.gradeList.add(score);
}
public double getAverage(ArrayList<Integer> gradeList) {
Integer aScore = 0;
if (!gradeList.isEmpty()) {
for (Integer grade : gradeList) {
aScore += grade;
}
return aScore.doubleValue() / gradeList.size();
}
return aScore;
}
}
First: I think the getAverage Method should use the internal ArrayList instead of a parameter.
Otherwise you don't have any read access to that lists contents.
You can use your GradeManager in the following way:
GradeManager manager = new GradeManager();
while(condition) {
int score = readScoreFromInput();
manager.addScore(score);
}
double averageScore = manager.getAverage();
print(averageScore);
So you get the average of all the scores you have just input.
The concrete implementation of the loop (and the exit condition) is up to you - it could be a predefined number of iterations or a special input like -1 for example.