I'm currently working on an assignment for my programming class and I cannot figure out why my output is coming out wrong.
We are supposed to "Print the “Difference” of population from the previous year. (Of course, this value is blank for the first year in the list.)
Use format control to print the values for Year, Population value and Difference from previous year. "
And my teacher gave us what the output is supposed to look like:
Desired Output:
But I keep getting this:
My Output:
This is my code:
import java.util.Scanner;
import java.io.*;
public class AssignmentOne
{
public static void main(String[] args) throws IOException
{
// Array Version
ArrayVersion();
System.out.println("Finished Array Version of Assignment");
}
// Method for ArrayVersion
public static void ArrayVersion() throws IOException
{
// Year as variables
int year = 1950;
final int ARRAY_SIZE = 41;
// Array to use for Population data
int[] population = new int[40];
// Call the method to get data into array
population = getDataFromFile("USPopulation.txt");
if(population == null)
{
System.out.println("Error: Population did not load");
return;
}
// Output
System.out.println("This is the Simple Array Version of \nPopulation Data US");
System.out.println("\nYear \tPopulation \tDifference");
System.out.println("");
System.out.printf("%d \t%,d,000\n", year, population[0]);
for(int i = 1; i < population.length; i++)
{
System.out.printf("%d \t%,d,000 \t%,d,000 \n", ++year, population[i], Math.abs(population[i] - population[++i]));
}
// Calculating the average + displaying it
int sum = 0;
for(int g = 0; g < population.length; g++)
{
sum += population[g];
}
int average;
average = sum / population.length;
System.out.println("Average:" + average);
}
// Method to get data from specified "filename" into an array of ints
public static int[] getDataFromFile(String USPopulation) throws IOException
{
// Array to use for Population data
// Opening file
File file = new File("E:/Programming 2/Assignment 1/src/USPopulation.txt");
Scanner inputFile = new Scanner(file);
int fileSize = 0;
while(inputFile.hasNext())
{
inputFile.nextInt();
fileSize++;
}
Scanner input2 = new Scanner(file);
int[] fileData = new int[fileSize];
for(int i = 0; i < fileSize; i++)
{
fileData[i] = input2.nextInt();
}
// System.out.println(fileData[40]);
// return the array fileData
return fileData;
}
population[++i]
There's your problem.
The prefixed increment simply increments the value of i before it gets the value, where i++ gets the value then increments i.
Just change it to population[i+1] and you'll be good. :P
Edit:
for(int i = 1; i < population.length; i++)
{
System.out.printf("%d \t%,d,000 \t%,d,000 \n", ++year, population[i], population[i] - population[i-1]);
}
The whole problem is in this line:
System.out.printf("%d \t%,d,000 \t%,d,000 \n", ++year, population[i], Math.abs(population[i] - population[++i]));
First, using ++i bumps your loop counter i one extra time per iteration, so you're only looking at every other year. No doubt you were trying to find the difference between one year's population and that of the next year; the correct way to look at next year's population would have been population[i+1]. But, as you say, using population[i+1] eventually gives you IndexOutOfBoundsException. Well, that's because when i is pointing to the last year, i+1 points beyond the end of the array of population data.
The second problem, then, is that you really want to be finding the difference between each year's population and that of the previous year: population[i] - population[i - 1]. So now, when i points at the last year, i-1 will still be within the array bounds, and because your loop actually starts with i == 1, i - 1 will still be a valid index.
Related
I have participated in coding contest, where I have attempt the given problem, so I am supposed to come up with solution which should not only passing all the test cases, also well optimized in terms of time and space complexity, I have passed 3 out of 7 but I am still not able to identify the rest of the test cases, it is possible that I might be missing something, please help me to rectify the below problem statement.
PROBLEM STATEMENT:
The Powerpuff Girls (100 Marks)
Professor Utonium is restless because of the increasing crime in the world. The number of villains and their activities has increased to a great extent. The current trio of Powerpuff Girls is not well to fight the evils of the whole world. Professor has decided to create the maximum number of Powerpuff Girls with the ingredients he has.
There are N ingredients required in a certain quantity to create a Powerpuff Girl. Professor has all the N ingredients in his laboratory and knows the quantity of each available ingredient. He also knows the quantity of a particular ingredient required to create a Powerpuff Girl. Professor is busy with the preparations and wants to start asap.
The villains, on the other hand, want to destroy the laboratory and stop Professor Utonium from creating more Powerpuff girls. Mojo Jojo is coming prepared with ammunition and Him is leading other villains like Princess, Amoeba Boys, Sedusa, Gangreen Gang etc.
Professor does not have much time as villains will reach the laboratory soon. He is starting the process but does not know the number of Powerpuff Girls which will be created. He needs your help in determining the maximum number of Powerpuff Girls which will be created with the current quantity of ingredients.
Example:
Professor Utonium requires 3 ingredients to make Powerpuff Girls. The 3 ingredients are present in the laboratory in the given quantity:
To make a Powerpuff Girl, Professor Utonium requires:
3 units of Ingredient A
6 units of Ingredient B
10 units of Ingredient C
The maximum number of Powerpuff Girls that can be created is 3 as, after 3, Professor will run out of Ingredient C.
Can you determine the maximum number?
Input Format
The first line of input consists of the number of ingredients, N
The second line of input consists of the N space-separated integers representing the quantity of each ingredient required to create a Powerpuff Girl.
The third line of input consists of the N space-separated integers representing the quantity of each ingredient present in the laboratory.
Constraints
1<= N <=10000000 (1e7)
0<= Quantity_of_ingredient <= LLONG_MAX
Output Format
Print the required output in a separate line.
Sample TestCase 1
Input
4
2 5 6 3
20 40 90 50
Output
8
SOLUTION CODE
package com.mzk.poi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class PowerPuffGirls {
private static final String SPACE = " ";
private static final Integer INITAL_IDX = 0;
private static final Integer LOWER_IDX = 1;
private static final Integer SECOND_IDX = 2;
private static final Integer MAX_LINES = 3;
private static final Integer UPPER_IDX = 1000000;
private static String[] UnitsArr = null;
private static String[] totIngrdientsArr = null;
private static int size = 0;
public static void main(String[] args) {
List<Integer> maxPowerPuffGirlsCreationList = new ArrayList<Integer>();
Scanner stdin = new Scanner(System.in);
String[] input = new String[MAX_LINES];
try {
for (int i = 0; i < input.length; i++) {
input[i] = stdin.nextLine();
if (validateIngredienInput(input[INITAL_IDX])) {
System.exit(INITAL_IDX);
}
}
} finally {
stdin.close();
}
int numOfIngredients = Integer.parseInt(input[INITAL_IDX]);
String units = input[LOWER_IDX];
UnitsArr = units.split(SPACE);
String ingredients = input[SECOND_IDX];
totIngrdientsArr = ingredients.split(SPACE);
size = UnitsArr.length;
int[] specifiedArrayOfUnits = convertToIntegerArray(UnitsArr);
int[] totIngredientInLabArray = convertToIntegerArray(totIngrdientsArr);
for (int i = 0; i < size; i++) {
totIngredientInLabArray[i] = Integer.parseInt(totIngrdientsArr[i]);
}
for (int i = 0; i < numOfIngredients; i++) {
maxPowerPuffGirlsCreationList.add(totIngredientInLabArray[i] / specifiedArrayOfUnits[i]);
}
System.out.println(Collections.min(maxPowerPuffGirlsCreationList));
}
/**
* This method validates the first input
* #param noOfIngredients
* #return boolean
*/
private static boolean validateIngredienInput(String noOfIngredients) {
int numOfIngredients = Integer.parseInt(noOfIngredients);
boolean result = false;
if (numOfIngredients <= LOWER_IDX && numOfIngredients <= UPPER_IDX) {
result = true;
return result;
}
return result;
}
/**
* This utility method convert the String array to Integer array
* #param size
* #param specifiedArrayOfUnits
* #return int[]
*/
private static int[] convertToIntegerArray(String[] arrayToBeParsed) {
int array[] = new int[size];
for (int i = INITAL_IDX; i < size; i++) {
array[i] = Integer.parseInt(arrayToBeParsed[i]);
}
return array;
}
}
The above solution has passed 3 test cases, remaining 7 are un identfied,Please help me to rectify or improve this code.
There are several issues with your code:
try {
for (int i = 0; i < input.length; i++) {
input[i] = stdin.nextLine();
if (validateIngredienInput(input[INITAL_IDX])) {
System.exit(INITAL_IDX);
}
}
} finally {
stdin.close();
}
You don't need to check the first row each time you read one line from the input. Instead you run the test only once. You can run it once you read the first line or after you read the whole input. The code can be look like this:
for (int i = 0; i < input.length; i++) {
input[i] = stdin.nextLine();
}
if (!validateIngredienInput(input[INITAL_IDX])) {
System.exit(...);
}
Also, it is not clear what the return value of validateIngredienInput() means. Is true a correct input or is false? Your if() statements checks for the return value being true and quits if it is.
private static boolean validateIngredienInput(String noOfIngredients)
{
int numOfIngredients = Integer.parseInt(noOfIngredients);
boolean result = false;
if (numOfIngredients <= LOWER_IDX && numOfIngredients <= UPPER_IDX) {
result = true;
return result;
}
return result;
}
Your if() condition doesn't make any sense. You are checking if the number of different ingredients is <= 0 and <= 1. This also means that you could rewrite is as just if (numOfIngredients <= 0). But with the description above it is unclear if the validation should return true or false. Depending on what this method should do it can be written as:
private static boolean validateIngredienInput(String noOfIngredients)
{
int numOfIngredients = Integer.parseInt(noOfIngredients);
return numOfIngredients > 0;
}
This will return true if the value is greater than 0.
UnitsArr = units.split(SPACE);
Variable and field names should begin in lowercase, so they don't get confused with class names, which start in uppercase. It looks like UnitsArr is a class, but it is actually a field. So you should rename your field to unitsArr:
unitsArr = units.split(SPACE);
Also check the requirement/format of the input and the limits:
Constraints
1<= N <=10000000 (1e7)
0<= Quantity_of_ingredient <= LLONG_MAX
As you see the quantity of ingredient can be a long value, but you are using Integer.parseInt() and int[] arrays for storing the quantity. You must change this to long to read long values from the input.
int[] totIngredientInLabArray = convertToIntegerArray(totIngrdientsArr);
for (int i = 0; i < size; i++) {
totIngredientInLabArray[i] = Integer.parseInt(totIngrdientsArr[i]);
}
You are converting the String array to an int array with your helper method convertToIntegerArray(), but then you are doing it again with the for loop. You can skip one of the two.
You might also want to check at: What is a debugger and how can it help me diagnose problems?
i'm trying to make a little program thar throws "reservaDados" number of dice and compare the "dado" (who is a number between 1-10) to a specified dificulty. Then i want to print the count of the number of exits, fails and ultrafails, but i seem to have a problem with the number of times the loop works, it only prints 9 results and i don't seem to find why, i supose that it has to do something with the counter i?
import java.util.*;
public class ProgramTUI {
public static void main(String[] args) {
Scanner var = new Scanner(System.in).useLocale(Locale.ENGLISH);
System.out.print("Cuantos dados lanzas?");
int reservaDados = var.nextInt();
System.out.print("Cual es la dificultad?");
int dificultad = var.nextInt();
int i = 0;
int numero_exitos = 0;
int numero_fracasos = 0;
int numero_pifias = 0;
while (i < reservaDados) {
i++;
int dado = (int) (Math.random() * 10) + 1;
if (reservaDados == i) {
System.out.println("Has sacado " + numero_exitos + " exitos, " + numero_fracasos
+ " fracasos, " + numero_pifias + " pifias");
} else if (dado == 1) {
numero_pifias++;
} else if (dado < dificultad) {
numero_fracasos++;
} else {
numero_exitos++;
}
}
}
}
In the last iteration, no more counting is done, only the result is printed. So you effectively miss one iteration.
Could be fixed by removing the first else, or by doing one extra iteration.
But just take the whole result printing out of the loop and place it directly after the loop. That will make the intent of the code much clearer.
Thilo is right, in the last pass of the loop it dosn't count the dice because ther is a print first, i just taked out the print, and pasted at the end like this:
import java.util.*;
public class ProgramTUI {
public static void main(String[] args) {
Scanner var = new Scanner(System.in).useLocale(Locale.ENGLISH);
System.out.print("Cuantos dados lanzas?");
int reservaDados= var.nextInt();
System.out.print("Cual es la dificultad?");
int dificultad= var.nextInt();
int i=0;
int numero_exitos=0;
int numero_fracasos=0;
int numero_pifias=0;
while (i < reservaDados){
i++;
int dado= (int) (Math.random() * 10) + 1;
if (dado == 1) {numero_pifias++;}
else if (dado < dificultad) {numero_fracasos++;}
else {numero_exitos++;}
if (reservaDados == i){System.out.println("Has sacado "+numero_exitos+" exitos, "+numero_fracasos+" fracasos, "+numero_pifias+" pifias");}
}
}
}
And it was fixed, thanks!
Build/Output Histograms using Arrays Where i'm wrong?
This code takes 5 inputs from user in array and show the number of stars for example if user enter 3 then *** would be shown and so on .Where i'm wrong ?
public class P20 {
public static void main(String[] args) {
int[] anArray;
int Number;
//setup variable value
anArray = new int [10];
System.out.println("Enter some numbers between 1 and 100.");
for (int i = 0; i < 10; i++) {
System.out.println(i);
anArray[0] = 1-9;
anArray[1] = 10-19;
anArray[2] = 20-29;
anArray[3] = 30-39;
anArray[4] = 40-49;
anArray[5] = 50-59;
anArray[6] = 60-69;
anArray[7] = 70-79;
anArray[8] = 80-89;
anArray[9] = 90-100;
if(anArray > 0) {
System.out.println("*"+Number );
else if(anArray > 20)
{
System.out.println("**"+Number );
}
else if (anArray > 30)
{
System.out.println("***"+Number );
}
else if (anArray > 40)
{
System.out.println("****"+Number );
}
else if (anArray > 50)
{
System.out.println("*****"+Number ); }
}}
This code takes 5 inputs from user in array and show the number of stars for example if user enter 3 then *** would be shown and so on .Where i'm wrong ?
This code doesn't take inputs from the user.
You want the user to input a value and then you print the number of stars he/she wrote. You could do this like that:
public class P20 //Why don't you try giving names that are easier to remember
{
public static void main(String[] args)
{
for (int i=0; i<args[0]; i++)
{
System.out.print("*");
}
}
Where args[0] is the first argument given to the program when called:
java P20 3
Anyway, let me try to point out what some of the mistakes of your code are:
When you wrote:
anArray[0] = 1-9;
Did you really want to write that wich means "Let the 0th element of the array be the number 1 minus 9" (=-8)?
Or did you intent to input an interval? (Meaning the numbers from 1 to 9).
Then later on you say
if(anArray > 0)
Which doesn't make sense to me since anArray is an int[] variable and not an int variable. This means that anArray is not a variable which points directly to a number, but one pointing to an array object which holds several int values.
if(anArray > 0) {
you always will be > 0 so you always get only 1 x *
you hve to modify your if clause like that:
if (anArray > 0 && anArray < 20){
and so on...
edit:-----------------------------------------------------------
like you requested:
public String stars(int n) {
if (n == 1){
return "*";
}else{
return "*" + stars(n-1);
}
}
I'm trying to write a program that opens a txt file and display information from that txt file. Java is my first language, and I'm taking java as a second language class since there's no beginning java class in my school. I'm struggling with this code for about an week. Any little help would be helpful. Appreciate for your help.
It keeps saying :
Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException:6
at store.Franchise.<init>(Franchise.java:10)
at store.FileIO.readData(FileIO.java:10)
at store.Driver.main(Driver.java:9)
Here is what I've got:
Sample txt file:
Day1 Day2 Day3 Day4 Day5
2541.56 2258.96 2214 2256 2154
2041.56 1758.96 1714 1756 1654
3041.56 2758.96 2714 2756 2654
3563.54 3280.94 3235.98 3277.98 3175.98
2547.21 2264.61 2219.65 2261.65 2159.65
4040.55 3757.95 3712.99 3754.99 3652.99
Store.java:
package store;
import java.io.IOException;
public class Store {
private float salesByWeek[][];
public Store() {
salesByWeek = new float[5][7];
// assign the array value at index 5, t to salesByWeek
}
public void setSaleForWeekDayIntersection(int week, int day, float sale) {
salesByWeek[week][day] = sale;
// store the sale value to SalesByWeek array at the index pointed to by week, day
// for exaample, it can be week 2 and day 3 (Wednesday)
}
float[] getSalesForEntireWeek(int week) {
// this will find the total sales for the whole week - all 5 days or 7 days including week ends Saturday and Sunday
float[] sales = new float[7];
// declare an array of type float and of size 7 - name the array as sales
for (int d = 0; d < 7; d++)
{
sales[d] = salesByWeek[week][d];
// the index d runs from 0 to 7
}
return sales;
}
float getSaleForWeekDayIntersection(int week, int day) {
return salesByWeek[week][day];
// the return value is the arraycontent pointed to by index week and day
}
float getTotalSalesForWeek(int week) {
float total = 0;
for (int d = 0; d < 7; d++)
{
total += salesByWeek[week][d];
// increment total by adding the array content salesByWeek at index week, d ( if d is the day)
}
return total;
// send the value of total back to the caller function
}
float getAverageSalesForWeek(int week) {
return getTotalSalesForWeek(week) / 7;
// divide the total sales for the whole week by 7 so that we get the average sales and return it
}
float getTotalSalesForAllWeeks() {
float total = 0; // declare a total variable of type float and initialize to 0 ( zero)
for (int w = 0; w < 5; w++)
{
total += getTotalSalesForWeek(w);
// sum up the total for the whole week and store it to the total variable
}
return total;
// return the sum computed above
}
float getAverageWeeklySales() {
return getTotalSalesForAllWeeks() / 5;
// AVERAGE for 5 days - just Monday to Friday only - excludes the week ends
}
int getWeekWithHighestSaleAmount() {
// top performing sales in the whole week
int maxWeek = 0;
float maxSale = -1;
for (int w = 0; w < 5; w++)
// run the for loop from 0 to 5 in steps of 1
{
float sale = getTotalSalesForWeek(w);
// first store the total sales in to the sale variable of type float
if (sale > maxSale)
{ // if at all if we find any amount greater than the max sale then replace max sale with the new sale amount
// and also note down the contributor - in the sense that which w ( week) achieved top sales
maxSale = sale;
maxWeek = w;
}
}
return maxWeek;
}
int getWeekWithLowestSaleAmount() {
int minWeek = 0;
float minSale = Float.MAX_VALUE;
for (int w = 0; w < 5; w++)
{
float sale = getTotalSalesForWeek(w);
if (sale < minSale)
{
minSale = sale;
minWeek = w;
}
}
// comments are same as the top sales except in reverse order
// first store an arbitary minimum sale figure
// then compare each running week's vaue with the lowest
// if at all when we encounter any value lower than the preset value then replace it
return minWeek;
// finally return the minimum value in that week
}
public void analyzeResults() {
for (int w = 0; w < 5; w++) // run the for loop from 0 to 5
{
System.out.printf("---- Week %d ----\n", w); // print a title decoration
System.out.printf(" Total sales: %.2f\n", getTotalSalesForWeek(w)); // display or print out the total sales summed earlier in called function
System.out.printf(" Average sales: %.2f\n", getAverageSalesForWeek(w)); // display the average sales figure
}
System.out.printf("\n");
System.out.printf("Total sales for all weeks: %.2f\n", getTotalSalesForAllWeeks()); // print sum of the sales for the entire week
System.out.printf("Average weekly sales: %.2f\n", getAverageWeeklySales()); // print weekly average sales
System.out.printf("Week with highest sale: %d\n", getWeekWithHighestSaleAmount()); // print highest performing or top sales
System.out.printf("Week with lowest sale: %d\n", getWeekWithLowestSaleAmount()); // print lowest sales or the struggling week
}
public void setsaleforweekdayintersection(int week, int day, float f) {
}
}
Franchise.java:
package store;
public class Franchise {
private Store stores[];
public Franchise(int num) { // now for a franchise store
stores = new Store[num]; // instantiate an array object of type class Store
// the class is Store
// the objects are named as stores
for(int i=0; i<=num; i++) stores[i] = new Store();
}
public Store getStores(int i) { // GETTER display or return values
return stores[i];
}
public void setStores(Store stores, int i) { // setter assign values
this.stores[i] = stores;
}
}
FileIO.java:
package store;
import java.io.*;
import java.util.StringTokenizer;
public class FileIO {
// Franchise readData(String filename)
Franchise readData(String filename, int numstores) {
Franchise f1 = new Franchise(numstores);
boolean DEBUG = true;
int ctr = 0;
// open the file
// read the line
// parse the line - get one value
// and set it in the correct location in 2 d array
try {
FileReader file = new FileReader(filename); // file is equivalent to a file pointer in c/c++
BufferedReader buff = new BufferedReader(file); // buffered reader will read a chunk in to the variable buff
boolean eof = false;
while (!eof) {
String line = buff.readLine();
ctr++;
if (line == null)
eof = true;
else {
if (DEBUG)
System.out.println(line);
if (ctr > 1) {
StringTokenizer a = new StringTokenizer(line);
for (int week = 0; week < 5; week++) {
for (int day = 0; day < 7; day++) {
String l = a.nextToken();
float f = Float.parseFloat(l); // parseFloat will store to variable f of type float
f1.getStores(ctr - 2)
.setsaleforweekdayintersection(week,
day, f);
if (DEBUG)
System.out.print("f" + f + " ");
}
}
}
}
}
} catch (IOException f2) {
}
return f1;
}
}
Driver.java:
package store;
public class Driver
{
public static void main(String[] args)
{
FileIO readdata = new FileIO();
Franchise f1 = readdata.readData("E:/Files/Salesdat.txt", 6);
System.out.println("Data read");
}
}
DriverImpl.java ( I got no idea why I need this subclass, but my tutor told me that I need this):
package store;
public class DriverImpl extends Driver {
}
I would like to change the line 10 in Franchise.java to
for(int i=0; i<num; i++) stores[i] = new Store();
Notice I removed the <= and put an = instead. Whenever dealing with array indices, one should always use the < comparator with the size as a good practice.
Valid indexes in an array are 0 to length - 1. Change <= to < like,
stores = new Store[num];
// the class is Store
// the objects are named as stores
for(int i=0; i<num; i++) stores[i] = new Store(); //stores[num] is invalid.
I currently have this program read the contents of a text file and calculate the averages and amount of test scores taken and print them out neatly in a small data table. These are the names, amount of quizes taken and average of each student:
James Tiberius Kirk 8 91.63
Buffy Summers 7 83.14
Tom Baker 15 100.00
Malcolm Reynolds 9 84.22
Elizabeth Bennet 9 93.33
John Blutarsky 9 0.00
Dorthy Gale 6 85.83
All of these Students are stored within the Array named Anames[]. I was wondering if it was at all possible to sort these students alphabetically by last name using the code that I have now. When I run the program it gives me the error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1927)
at text.reader.TextReader.compareLastNames(TextReader.java:117)
at text.reader.TextReader.main(TextReader.java:94)
Here is the code of my main class:
public static void main(String[] args)throws IOException{
Double score=0.0;
int b,j;
String tempfirst = "";
String templast = "";
Student Anames[] = new Student[30];
Student Temp[] = new Student [1];
int Stucount = 0;
Scanner reader = new Scanner(new File("quizScores.txt"));
boolean runProgram = true;
PrintWriter writer = new PrintWriter(new File("scoreReport.txt"));
//prints header for report
System.out.println("Name Number Quizes Quiz Socres");
writer.println("Name Number Quizes Quiz Socres");
//check to see if end of file string
while (!reader.hasNext("-10")){
String name="", first="", last="";
//gets the name from file
while(!reader.hasNextDouble()){
last = reader.next();
while (!reader.hasNextDouble()){
first = first+reader.next()+" ";
}
name=first+last;
}
//creates new student with given name
Student newStudent = new Student(first, last);
Anames[Stucount] = newStudent;
Stucount++;
//gets the quiz scores and makes sure does not averge in the end of file string.
while (reader.hasNextDouble()&& !reader.hasNext("-10")){
newStudent.addQuiz(reader.nextDouble());
}
//Prints out the formated data
System.out.printf("%-30s%4.0f%30.2f \n",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
writer.printf("%-30s%4.0f%30.2f",newStudent.getName(), newStudent.getQuizNumber(), newStudent.getAverage());
writer.println();
}
System.out.println("\n");
for (b = 0; b < Stucount; b++){
int INTEGERTEMP = b;
for (j= b+1; j < Stucount; j++){
int INTEGERTEMP2 = j;
if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
Temp[0] = Anames[b];
Anames[b] = Anames[j];
Anames[j] = Temp[0];
}
}
}
System.out.println("Name Number Quizes Quiz Socres");
for (int i = 0; i < Stucount; i++) {
System.out.printf("%-30s%4.0f%30.2f \n", Anames[i].getName(), Anames[i].getQuizNumber(), Anames[i].getAverage());
}
writer.close();
}
private static int compareLastNames(String a, String b){
int index_a = a.lastIndexOf(" ");
String surname_a = a.substring(index_a);
int index_b = b.lastIndexOf(" ");
String surname_b = b.substring(index_b);
int lastNameCmp = surname_a.compareToIgnoreCase(surname_b);
return lastNameCmp;
}
Here is the Student.java which contains most of the methods used:
public Student (String inName, String inLast){
studentName=inName;
studentLast = inLast;
quizAverage = 0;
quizScore=0;
numberQuizes=0;
}
public void addQuiz(double inQuiz){
quizScore += inQuiz;
numberQuizes++;
}
public double getAverage(){
quizAverage = quizScore/numberQuizes;
return quizAverage;
}
public String getName(){
return studentName+studentLast;
}
public double getQuizNumber(){
return numberQuizes;
}
public String getLAST(){
return studentLast;
}
You can use java.util.Arrays.sort(Student [] arr, Comparator<Student> comp) instead of your own compare code. In single line you can achieve it like this:
Student arr[];//considering this array you will populate
Arrays.sort(arr,new java.util.Comparator<Student>(){
public int compare(Student o1, Student o2) {
return o1.studentLast.compareTo(o2.studentLast);
}
});
//then the arr will be sorted with studentLast name
Let's work our way back from your exception to figure out where the problem is. First, it tells us we've got a StringIndexOutOfBoundsException on line 117; that is, the line (it might actually be the surname_b line, you've removed code from the class that means I can't match up the lines properly)
String surname_a = a.substring(index_a);
You'll notice the message from the exception helpfully tells us that the index used was -1. Let's take a look at why a.lastIndexOf(" "); would return -1. We see in the documentation for String that it returns -1 when the character does not occur in the String.
Now, let's work another step back in the Exception's stack trace to figure out why there's no space in that String. The Exception tells us to check line 94, where we see
if ((compareLastNames(Anames[INTEGERTEMP].getLAST(), Anames[INTEGERTEMP2].getLAST()))>0){
So, what's going on here? We're passing in the last names (and just the last names) from each of the students into our comparison function. The last names, for the most part, have no spaces in them.
So, how do we fix this? Well, you'll have to change your function to only take substrings of the surname if there actually is a space in them, i.e. if the index returned isn't -1.
Once you've got the comparison function done, I recommend looking at how to write an Object that implements the Comparable interface. This will allow you to use library sorting functions, which will be faster and less buggy than your own sorting functions (most likely!).