Need to perform calculations on array within Object array - java

I have an array of 15 Student objects that consist of an int (student ID) and an array (scores for 5 lab assignments). I am required to calculate the Low, High, and Avg scores for each of the 5 labs. The only way I can think of doing this is looking at all the arrays by columns, but my arrays are a row for each student. How would I go about doing these calculations on these arrays.
Included is a Util class which the Student object array comes from and a Student class to define the object. I only need help with the Statistics class provided.
Any help would be greatly appreciated!
Util.class:
import java.io.*;
import java.util.*;
import java.lang.*;
public class Util {
public static Student[] readFile(String fileName) {
Student studentArray[]=new Student[15];
try{
FileReader file = new FileReader("studentData.txt");
BufferedReader buff = new BufferedReader(file);
String line;
line = buff.readLine();
int index=0;
while(line != null){
System.out.println(line);
if(index>14){
break;
}
line = buff.readLine();
String[] result = line.split("\\s");
int sid = Integer.parseInt(result[0]);
int scores[] = new int[5];
for(int x=1;x<result.length;x++){
scores[x-1] = Integer.parseInt(result[x]);
}
Student myCSC20Student = new Student(sid, scores);
studentArray[index++] = myCSC20Student;
}
}
catch (IOException e){
System.out.println("Error: " + e.toString());
}
return studentArray;
}
}
Student.class:
import java.io.*;
import java.util.*;
public class Student {
final int LABS = 5;
private int SID;
private int scores[] = new int[LABS];
public Student(int sid, int[] scores)
{
this.SID=sid;
this.scores = scores;
}
//getters and setters for SID and scores
public int getID() {
return SID;
}
public void setID(int x) {
this.SID = x;
}
public int[] getScore() {
return scores;
}
}
Statistics.class:
import java.io.*;
import java.util.*;
public class Statistics {
final int LABS = 5;
public int[] lowscores = new int[LABS];
private int[] highscores = new int[LABS];
private float[] avgscores = new float[LABS];
public static void main(String args[]) {
Student[] studArr = Util.readFile("studentData.txt");
System.out.println("");
for(int i=0; i<=studArr.length-1; i++){
System.out.println(Arrays.toString(studArr[i].getScore()));
}
}
void calculateLow(Student[] a){
}
void calculateHigh(Student[] a){
}
void calculateAvg(Student[] a){
}
}
Output Class:
import java.util.*;
public class Output{
public static void main(String[] args){
Student[] studArr = Util.readFile("studentData.txt");
Statistics statistics = new Statistics();
statistics.calculateLow(studArr);
statistics.calculateHigh(studArr);
statistics.calculateAvg(studArr);
System.out.println("Low scores:");
System.out.println(Arrays.toString(statistics.getLowscores()));
System.out.println("High scores:");
System.out.println(Arrays.toString(statistics.getHighscores()));
System.out.println("Average scores:");
System.out.println(Arrays.toString(statistics.getAvgscores()));
}
}
Output of scores of all 15 students for the 5 labs

#Bogdan-Lukiyanchuk provided a solution that utilizes Java streams. I am of the impression the assignment is designed to only use loops and arrays. As such, a pointer to the solution is something along the lines of:
void calculateLow(Student[] a) {
// if we don't have any students, then just leave
if (a == null || a.length == 0) {
return;
}
// set to the maximum score one could possibly have
int lowScore = Integer.MAX_INT;
Student lowPersonOnTotem = null;
// process all of the students
for (Student student : a) {
int[] scores = student.getScore();
// loop over all of the scores; if the score is lower than any
// previous, update the lowScore and who had it
for (int score : scores) {
if (score < lowScore) {
lowScore = score;
lowPersonOnTotem = student;
}
}
}
System.out.printf("Lowest score of all students is %d achieved by %d\n",
lowScore, lowPersonOnTotem.getId());
}
Now, following from the critique by #markspace in the comments, I would think having calculateLow() return a value and then have the display elsewhere would be most appropriate, but the method was marked as void in the OP's example.
The other methods are essentially the same loop, but the math changes.

import java.util.*;
public class Statistics {
final int LABS = 5;
public int[] lowscores = new int[LABS];
private int[] highscores = new int[LABS];
private float[] avgscores = new float[LABS];
public static void main(String args[]) {
Student[] studArr = Util.readFile("studentData.txt");
System.out.println();
for(int i=0; i<=studArr.length-1; i++){
System.out.println(Arrays.toString(studArr[i].getScore()));
}
Statistics statistics = new Statistics();
statistics.calculateLow(studArr);
statistics.calculateHigh(studArr);
statistics.calculateAvg(studArr);
System.out.println("Low scores:");
System.out.println(Arrays.toString(statistics.getLowscores()));
System.out.println("High scores:");
System.out.println(Arrays.toString(statistics.getHighscores()));
System.out.println("Average scores:");
System.out.println(Arrays.toString(statistics.getAvgscores()));
}
public void calculateLow(Student[] a){
for (int i = 0; i < LABS; i++) {
final int lab = i;
lowscores[lab] = Arrays.stream(a)
.mapToInt(student -> student.getScore()[lab])
.min()
.orElse(0);
}
}
public void calculateHigh(Student[] a){
for (int i = 0; i < LABS; i++) {
final int lab = i;
highscores[lab] = Arrays.stream(a)
.mapToInt(student -> student.getScore()[lab])
.max()
.orElse(0);
}
}
public void calculateAvg(Student[] a){
for (int i = 0; i < LABS; i++) {
final int lab = i;
avgscores[lab] = (float) Arrays.stream(a)
.mapToInt(student -> student.getScore()[lab])
.average()
.orElse(0);
}
}
public int[] getLowscores() {
return lowscores;
}
public int[] getHighscores() {
return highscores;
}
public float[] getAvgscores() {
return avgscores;
}
}

Related

Sorting an array of objects? user input and comparator [duplicate]

This question already has answers here:
Why do I have NullPointerException in my sort implementation?
(3 answers)
Closed 6 years ago.
Trying to sort an array of objects by overallVisits from greatest to smallest but get an error. The goal is to pass in website objects to the array then have them sorted out according to greatest overall visit to least visit.
I get the following error:
Exception in thread "main" java.lang.NullPointerException at java.util.ComparableTimSort.binarySort(ComparableTimSort.java:258)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:185)
at java.util.Arrays.sort(Arrays.java:1246)
at Project1.main(Project1.java:32)
import java.util.Scanner;
import java.util.Arrays;
public class Project1
{
public static void main (String args[])
{
Scanner input = new Scanner(System.in);
Website [] websites = new Website[20];
String temp;
String temp2;
int days = 4;
for(int i=0; i < 10; i++)
{
System.out.println("Enter the URL of the Website:");
temp = input.nextLine();
websites[i] = new Website();
websites[i].setUrl(temp);
System.out.println("Enter the name of the Website:");
temp2 = input.nextLine();
websites[i].setName(temp2);
}
Arrays.sort(websites);
for(int i = 0; i<10; i++)
{
System.out.println("URL:" + websites[i].getUrl()+ " Current Visits:" + websites[i].getCurvisit() + " Overall Visits:" + websites[i].getOvrvisit());
System.out.println("Name of Website:" + websites[i].getName());
}
}
}
//Class 2:
import java.util.Scanner;
import java.util.Random;
public class Website implements Comparable <Website>
{
private String url;
private String name;
private int currentVisit;
private int overallVisit;
public Website()
{
this.url = url;
this.name = name;
this.currentVisit = getRandom1();
this.overallVisit = getRandom2();
}
public String getUrl()
{
return url;
}
public void setUrl(String s)
{
url = s;
}
public String getName()
{
return name;
}
public void setName(String n)
{
name = n;
}
public int getRandom1()
{
Random rand = new Random();
int num = rand.nextInt(4);
return num;
}
public int getRandom2()
{
Random rand = new Random();
int num2 = 10 + rand.nextInt(11);
return num2;
}
public int getCurvisit()
{
return currentVisit;
}
public int getOvrvisit()
{
return overallVisit;
}
public int compareTo(Website compareVisit)
{
int compareAll = ((Website) compareVisit).getOvrvisit();
return compareAll - this.overallVisit;
}
}
You're getting a java.lang.NullPointerException because you have allocated 20 elements in your array but have only filled it with 10.
New Array
Website [] websites = new Website[20];
Filling the array
for(int i=0; i < 10; i++)

Values not printed out when using Comparator to sort ArrayList

I'm working on a program where I'm inputting values(String and int) into arrays, putting those values into an objects which go into an array list to be sorted by the the int value. When I run the program though, it prints out:
Sorted List Entries:
Item Name:null---Quant:0
Item Name:null---Quant:0
Item Name:null---Quant:0 //etc..
I'm trying to learn on my own here but I'm not sure what to do.
My main class:
import java.io.*;
import java.util.*;
public class InputItem
{
public static void main(String args[])
{
String again;
String names[] = new String[100];
int quant[] = new int[100];
int row=0;
do{
System.out.println("Please input assignment name:");
Scanner newName = new Scanner(System.in);
String name = newNamet.next();
names[row] =name;
System.out.println("Please input assignment quant:");
Scanner quantI = new Scanner(System.in);
int quantity = quantI.nextInt();
quant[row] = quantity;
System.out.println("Would you like to add another item? Enter 'Yes' or 'No'");
Scanner input = new Scanner(System.in);
again = input.next();
row++;
}
while(again.equalsIgnoreCase("Yes"));
List<Items> work = new ArrayList<Items>();
for(int count = 0; count<row; count++)
{
work.add(new Items((names[row]),(quant[row])));
}
Collections.sort(work, new MyComp());
System.out.println("Sorted List Entries: ");
for(Items e:work)
{
System.out.println(e);
}
}
}
Class with Comparator:
import java.util.*;
class MyComp implements Comparator<Items>
{
#Override
public int compare(Items e1, Items e2)
{
if((e1).getQuant()< (e2).getQuant())
{
return 1;
}
else
{
return -1;
}
}
}
public class Items
{
private String name;
private int quant;
public Items(String n, int q)
{
this.name = n;
this.quant = q;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getQuant()
{
return quant;
}
public void setQuant(int quant)
{
this.quant = quant;
}
public String toString()
{
return "Item Name:" + this.name+"---Quant:" +this.quant;
}
}
The problem is here...
for (int count = 0; count < row; count++) {
work.add(new Items((names[row]), (quant[row])));
}
You're using row, which was defined in the previous section of code to keep track of which element you were updating, but is now pointing to the next element in the array (or an empty element). This basically means you are constantly adding the same (empty) values to your Items
Instead, you should be using count
for (int count = 0; count < row; count++) {
work.add(new Items((names[count]), (quant[count])));
}

Implementing merge sort in java 7

I have a problem with implementation of merge sort in java. I am looking for the error almost week unfortunately without result. ArrayList at the entrance is the same as the output.
import java.util.ArrayList;
import java.util.Scanner;
public class MergeSort
{
private ArrayList<Integer> basicArrayList = new ArrayList<Integer>();
ArrayList<Integer> arrayListA = new ArrayList<Integer>();
ArrayList<Integer> arrayListB = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
private int firstIndexOfArrayList = 0;
private int lastIndexOfArrayListA;
private int lastIndexOfArrayListB;
public void Scal(ArrayList<Integer> basicArrayList, int p, int q, int r) {
this.firstIndexOfArrayList = p;
this.lastIndexOfArrayListA = q;
this.lastIndexOfArrayListB = r;
int numberOfElementsArrayListA = lastIndexOfArrayListA
- firstIndexOfArrayList + 1;
int numberOfElementsArrayListB = lastIndexOfArrayListB
- lastIndexOfArrayListA;
for (int i = 0; i < numberOfElementsArrayListA; i++) {
arrayListA.set(i, basicArrayList.get(firstIndexOfArrayList + i));
}
for (int j = 0; j < numberOfElementsArrayListB; j++) {
arrayListB.set(j, basicArrayList.get(lastIndexOfArrayListA + j));
}
arrayListA.add(Integer.MAX_VALUE);
arrayListB.add(Integer.MAX_VALUE);
int i = 0;
int j = 0;
for (int k = firstIndexOfArrayList; k <= lastIndexOfArrayListB; k++) {
if (arrayListA.get(i) <= arrayListB.get(j)) {
basicArrayList.set(k, arrayListA.get(i));
i = i + 1;
} else {
basicArrayList.set(k, arrayListB.get(j));
j = j + 1;
}
}
}
public void MergeSort(ArrayList basicArrayList, int p, int r) {
this.firstIndexOfArrayList = p;
this.lastIndexOfArrayListB = r;
if (firstIndexOfArrayList < lastIndexOfArrayListB) {
int lastIndexOfArrayListA = (firstIndexOfArrayList + lastIndexOfArrayListB) / 2;
MergeSort(basicArrayList, firstIndexOfArrayList,
lastIndexOfArrayListA);
MergeSort(basicArrayList, lastIndexOfArrayListA + 1,
lastIndexOfArrayListB);
Scal(basicArrayList, firstIndexOfArrayList,
lastIndexOfArrayListA,
lastIndexOfArrayListB);
}
}
public void setSize() {
System.out.println("Enter the number of elements to sort: ");
this.lastIndexOfArrayListB = input.nextInt();
}
public int getSize() {
return lastIndexOfArrayListB;
}
public void setData() {
System.out.println("Enter the numbers: ");
for (int i = 0; i < lastIndexOfArrayListB; i++) {
int number;
number = input.nextInt();
basicArrayList.add(number);
}
}
public void getTable() {
System.out.println(basicArrayList.toString());
}
public static void main(String[] args) {
MergeSort output = new MergeSort();
output.setSize();
output.setData();
output.MergeSort(output.basicArrayList,
output.firstIndexOfArrayList, (output.getSize() - 1));
output.getTable();
}
}
In terms of fixing your code I had a crack at it and as far as I can tell this seems to work. To do this a lot of your code had to be changed but it does now sort all Integers properly
import java.util.ArrayList;
import java.util.Scanner;
public class MergeSort
{
private ArrayList<Integer> basicArrayList = new ArrayList<Integer>();
Scanner input = new Scanner(System.in);
private int numbersToSort;
public void doMergeSort(int firstIndexOfArrayList,int lastIndexOfArrayListB, ArrayList<Integer> arrayList)
{
if(firstIndexOfArrayList<lastIndexOfArrayListB && (lastIndexOfArrayListB-firstIndexOfArrayList)>=1)
{
int mid = (lastIndexOfArrayListB + firstIndexOfArrayList)/2;
doMergeSort(firstIndexOfArrayList, mid, arrayList);
doMergeSort(mid+1, lastIndexOfArrayListB, arrayList);
Scal(firstIndexOfArrayList,mid,lastIndexOfArrayListB, arrayList);
}
}
public void Scal(int firstIndexOfArrayList,int lastIndexOfArrayListA,int lastIndexOfArrayListB, ArrayList<Integer> arrayList)
{
ArrayList<Integer> mergedSortedArray = new ArrayList<Integer>();
int leftIndex = firstIndexOfArrayList;
int rightIndex = lastIndexOfArrayListA+1;
while(leftIndex<=lastIndexOfArrayListA && rightIndex<=lastIndexOfArrayListB)
{
if(arrayList.get(leftIndex)<=arrayList.get(rightIndex))
{
mergedSortedArray.add(arrayList.get(leftIndex));
leftIndex++;
}
else
{
mergedSortedArray.add(arrayList.get(rightIndex));
rightIndex++;
}
}
while(leftIndex<=lastIndexOfArrayListA)
{
mergedSortedArray.add(arrayList.get(leftIndex));
leftIndex++;
}
while(rightIndex<=lastIndexOfArrayListB)
{
mergedSortedArray.add(arrayList.get(rightIndex));
rightIndex++;
}
int i = 0;
int j = firstIndexOfArrayList;
while(i<mergedSortedArray.size())
{
arrayList.set(j, mergedSortedArray.get(i++));
j++;
}
}
public void setSize()
{
System.out.println("Enter the number of elements to sort: ");
this.numbersToSort = input.nextInt();
}
public int getSize()
{
return numbersToSort;
}
public void setData()
{
System.out.println("Enter the numbers: ");
for (int i = 0; i < numbersToSort; i++)
{
int number;
number = input.nextInt();
basicArrayList.add(number);
}
}
public void getTable()
{
System.out.println(basicArrayList.toString());
}
public void runSort(ArrayList<Integer> arrayList)
{
doMergeSort(0, this.numbersToSort-1, arrayList);
}
public static void main(String[] args)
{
MergeSort output = new MergeSort();
output.setSize();
output.setData();
output.runSort(output.basicArrayList);
output.getTable();
}
}
Try this code. The following code takes an ArrayList input and outputs an ArrayList as well so it still works along the same basis of your code. The actual sort is handled in a different class MergeSort and is passes into ForMergeSort. Hope this helps
MergeSort.java
public class MergeSort
{
private int[] array;
private int[] tempMergArr;
private int length;
public void sort(int[] inputArr)
{
}
public int[] getSortedArray(int[] inputArr)
{
this.array = inputArr;
this.length = inputArr.length;
this.tempMergArr = new int[length];
doMergeSort(0, length - 1);
for(int i=0;i<length;i++)
{
int correctNumber = i+1;
System.out.println("Value "+correctNumber+" of the sorted array which was sorted via the Merge Sort is: "+inputArr[i]);
}
return inputArr;
}
private void doMergeSort(int lowerIndex, int higherIndex)
{
if (lowerIndex < higherIndex)
{
int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
doMergeSort(lowerIndex, middle);
doMergeSort(middle + 1, higherIndex);
mergeParts(lowerIndex, middle, higherIndex);
}
}
private void mergeParts(int lowerIndex, int middle, int higherIndex)
{
for (int i = lowerIndex; i <= higherIndex; i++)
{
tempMergArr[i] = array[i];
}
int i = lowerIndex;
int j = middle + 1;
int k = lowerIndex;
while (i <= middle && j <= higherIndex)
{
if (tempMergArr[i] <= tempMergArr[j])
{
array[k] = tempMergArr[i];
i++;
}
else
{
array[k] = tempMergArr[j];
j++;
}
k++;
}
while (i <= middle)
{
array[k] = tempMergArr[i];
k++;
i++;
}
}
}
ForMergeSort.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class ForMergeSort
{
ArrayList<Integer> arrayList = new ArrayList<Integer>();
ArrayList<Integer> sortedArrayList = new ArrayList<Integer>();
MergeSort mS = new MergeSort();
public void buildArrayList()
{
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of elements to sort: ");
int toSort = input.nextInt();
System.out.println("Enter the numbers: ");
for(int i =0; i<toSort; i++)
{
int number = input.nextInt();
arrayList.add(number);
}
}
public void runMergeSort(ArrayList<Integer> arrayList)
{
int[] arrayOfValues = new int[arrayList.size()];
int i = 0;
for(int a:arrayList)
{
arrayOfValues[i] = a;
i++;
}
MergeSort mS = new MergeSort();
for(int intOfArray:mS.getSortedArray(arrayOfValues))
{
sortedArrayList.add(intOfArray);
}
System.out.println(sortedArrayList.toString());
}
public static void main(String[] args)
{
ForMergeSort fMS = new ForMergeSort();
fMS.buildArrayList();
fMS.runMergeSort(fMS.arrayList);
}
}

Creating a random generated array in method and printing it

So I'm pretty sure I've correctly created a random integer generator that will put the integers into an array, although I am having trouble with my second method, that is supposed to print out the array.
My code:
import java.util.Random;
import java.util.Scanner;
public class Engine {
public int numDigits, numDigitsSet;
public int i;
public int[] secretNumber;
public Random randomNumberGenerator;
Scanner sc = new Scanner(System.in);
public void setNumDigits()
{
numDigitsSet = numDigits;
}
public int getNumDigits()
{
System.out.print("Enter the number of digits to use: ");
return numDigits = sc.nextInt();
}
public void generateNewSecret()
{
Random rand = new Random();{
for (int i=0; i<numDigitsSet; i++)
{
secretNumber[i]= rand.nextInt(10);
System.out.println("" + secretNumber[i]);
}
}
}
public int[] getSecretNumber()
{
for (int j=0; j<secretNumber.length; j++)
{
System.out.println("" + secretNumber[j]);
}
return secretNumber;
}
public void convertNumtoDigitArray()
{
String[] userGuessSplit = Player.userGuess.split(",");
int[] userGuessArray = new int[userGuessSplit.length];
for (int j=0; j<userGuessSplit.length; j++)
{
userGuessArray[j] = Integer.parseInt(userGuessSplit[j]);
}
}
}
For printing out the array, you can use the seriously convenient
Arrays.toString(array);
JavaDoc: http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#toString(int[])

Add label after looping number

I made this code to calculate numbers:
import java.util.Random;
public class Sorting {
private double[] player;
private int k=5;
private int j=5;
public void sort(){
player = new double[k];
for(int i=1;i<k;i++){
double tempp ;
for(i=1;i<j;i++){
tempp = Math.random() * i;
player[i]=tempp;
System.out.println("Result "+i+"="+player[i]);
}
}
}
public static void main(String []args){
Sorting k=new Sorting();
k.sort();
}}
and the result is:
Result 1=0.4529689730194949
Result 2=0.09643822768644617
Result 3=1.841047494651026
Result 4=2.1807153629323777
Now, I want to add a label from the biggest to the smallest result number labeled EXCELLENT, VERY GOOD, GOOD and BAD like this:
Result 1=0.4529689730194949 labeled GOOD
Result 2=0.09643822768644617 labeled BAD
Result 3=1.841047494651026 labeled VERY GOOD
Result 4=2.1807153629323777 labeled EXCELLENT
public class Sorting
{
private double[] player;
private int k=5;
private int j=5;
String[] rating = {"BAD", "GOOD", "VERY GOOD", "EXCELENT"};
public void sort()
{
player = new double[k];
for(int i=1; i<k; i++)
{
double tempp;
for(i=1; i<j; i++) // i should probably be zero since your array starts on value 0, not 1.
{
tempp = Math.random() * i;
player[i]=tempp;
System.out.println("Result " + i + " = " + player[i] + " Rating is " + rating[(int)player[i]]);
}
}
}
public static void main(String[] args)
{
Sorting k = new Sorting();
k.sort();
}
}
your code seems a little odd but i fixed the problem you were asking about.
TreeSet already sort the numbers ascending by default.
Here my version:
Sample output:
Result: 0.12754837127918317 => BAD
Result: 0.7956890627771006 => EXCELLENT
Result: 0.3123868511945034 => GOOD
Result: 0.6332109887264882 => VERY_GOOD
public class FourRandomNumbersEvaluator {
private TreeSet<Double> numbers;
private Map<Double,Evaluation> numbersWithEvaluations = new HashMap<Double,Evaluation>();
private enum Evaluation {BAD, GOOD, VERY_GOOD, EXCELLENT}
private static final int NUMBER_OF_GENERATED_NUMBERS = 4;
public FourRandomNumbersEvaluator(TreeSet<Double> numbers) {
if(numbers == null || numbers.size() != 4){
throw new IllegalArgumentException("your have to provide exactly 4 numbers");
}
this.numbers = numbers;
}
public static void main(String[] args) {
FourRandomNumbersEvaluator evaluator = new FourRandomNumbersEvaluator(generateNumbers());
evaluator.evaluate();
evaluator.printNumbersWithEvaluations();
}
private static TreeSet<Double> generateNumbers() {
TreeSet<Double> numbers = new TreeSet<Double>();
while(numbers.size() < NUMBER_OF_GENERATED_NUMBERS){
double number = Math.random();
if(numberNotAlreadyExisting(numbers, number)){
numbers.add(number);
}
}
return numbers;
}
private static boolean numberNotAlreadyExisting(TreeSet<Double> numbers, double number) {
return !numbers.contains(number);
}
public void evaluate() {
int i = 0;
for(Double number : numbers){
numbersWithEvaluations.put(number, Evaluation.values()[i++]);
}
}
private void printNumbersWithEvaluations(){
for(Map.Entry<Double,Evaluation> numberWithEvaluation : numbersWithEvaluations.entrySet())
System.out.println("Result: "+ numberWithEvaluation.getKey() + " => " + numberWithEvaluation.getValue());
}
}

Categories

Resources