When I use the removeStudent
method it successfully removes the name of the student from the names
array but it throws an error when it's supposed to delete the student's grades from the marks
array.
import java.util.Objects;
import java.util.Scanner;
import java.util.Arrays;
public class Project {
//I've put the attributes of the arrays outside the main methods because the methods that I've made are not static
String[] names= {"Nadim", "Sarah","Alfred","Hala","Abed"};
double[][] marks= {
{90, 45, 67, 23, 35},
{100, 100, 100, 100, 100},
{79, 83, 86, 89, 99},
{80, 88, 50, 50, 50},
{81, 85, 88, 91, 90}
};
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Project Class = new Project();
System.out.println("""
Available Operations:\s
(add) To add a new student\s
(remove) To remove a Student\s
(find gpa) To get a student GPA
(print grades) To print the grades of a student\s
(find average) To get the average GPA of the class\s
(lowest gpa) To get the student with lowest GPA\s
(highest gpa) To get the student with highest GPA\s
(find student) To get the students who got a certain GPA
(quit) To Exit
""");
String operation;
String name;
do{
System.out.print("\nEnter the name of the operation to begin: ");
operation = scan.nextLine();
//this is the main switch statement that controls all the methods below
switch (operation) {
case "add" -> {
System.out.print("Enter the name of the student: ");
name = scan.nextLine();
Class.addStudent(name);
Class.addMarks();
}
case "remove" -> {
System.out.print("Enter the name of the student: ");
name = scan.nextLine();
Class.removeStudent(name);
}
case "find gpa" -> {
System.out.print("Enter the name of the student: ");
name = scan.nextLine();
Class.findGpa(name);
}
case "print grades" -> {
System.out.print("Enter the name of the student: ");
name = scan.nextLine();
Class.printStudentGrades(name);
}
case "find student" -> {
System.out.print("Enter the the GPA of the student: ");
double gpa = scan.nextDouble();
Class.findStudentByGpa(gpa);
}
case "lowest gpa" -> Class.lowestGpa();
case "highest gpa" -> Class.highestGpa();
case "find average" -> Class.findAverage();
}
}while (!Objects.equals(operation, "quit"));
}
public void addStudent(String nameAdd) {
//in the line below I made a new array that is one longer by one value to hold the new value of the added student name
String[] moreNames= new String[names.length 1];
//this loop copies the values of the old array to the new one
for (int i=0; i <names.length; i ) {
moreNames[i] = names[i];
}
//here we add the new name that is chosen by the user
moreNames[moreNames.length -1] = nameAdd;
names= moreNames;
}
public void addMarks() {
// Create a new 2D array with one more row than the original array
double[][] newMarks = new double[marks.length 1][];
// Copy the values from the original array to the new array
for (int i = 0; i < marks.length; i ) {
newMarks[i] = marks[i];
}
// Get the number of marks for the newly added student
System.out.print("Enter the number of marks for the new student: ");
Scanner scan = new Scanner(System.in);
int numMarks = scan.nextInt();
// Create a new array to hold the marks for the newly added student
newMarks[newMarks.length - 1] = new double[numMarks];
// Get the marks for the newly added student
for (int i = 0; i < numMarks; i ) {
System.out.print("Enter mark " (i 1) ": ");
newMarks[newMarks.length - 1][i] = scan.nextDouble();
}
// Replace the original marks array with the new array
marks = newMarks;
}
public void removeStudent(String nameToRemove) {
//making a new shorter array than the names array, so we can save the results to it
String[] newNames = new String[names.length-1];
int namesIndexLess=0;
//in the lines below are put to copy the names don't math the one selected of the old array to the new one
for (String name : names) {
if (!Objects.equals(name, nameToRemove)) {
newNames[namesIndexLess] = name;
namesIndexLess ;
}
}
//making the names array equal to the newNames so when we use the program again the last results will be saved
names = newNames;
System.out.println("The new list of student names is " Arrays.toString(names));
int plsWork =0;
for ( int i =0; i < names.length; i ) {
if (Objects.equals(nameToRemove, names[i])) {
plsWork = i;
}
}
double[][] newMarks = new double[marks.length-1][marks[0].length];
int count =0;
for (int i =0; i < marks.length; i ) {
if (i != plsWork) {
for (int y =0; y < marks[i].length; y ) {
newMarks[count][y] = marks[i][y];
count ;
}
}
}
}
public void printStudentGrades(String studentName) {
int studentIndex =0;
for (int i =0; i < names.length; i ) {
if (Objects.equals(studentName, names[i])) {
studentIndex = i;
}
}
for (int i =0; i <marks.length; i ) {
if (studentIndex == i) {
for (int p =0; p <marks[i].length; p ) {
System.out.println(marks[i][p]);
}
}
}
}
public void findStudentByGpa(double gpa) {
int y = -1;
int sum;
//in the line below I made a new array to hold the values that the loop will create from teh old array
double[] newMarks= new double[marks.length];
//the loop will make new values to then put in a new array that hold 5 summations of the old secondary arrays
for (int i= 0; i <marks.length; i ) {
y ;
sum = 0;
for (int j =0; j<marks[i].length; j ) {
sum = marks[i][j];
}
double initialGpa = sum/5;
newMarks[y] = initialGpa;
}
int index = 0;
for (int i =0; i < newMarks.length; i ) {
if (gpa == newMarks[i]) {
index = i;
}
}
System.out.println(names[index]);
}
public void findGpa(String nameSum) {
double sum= 0;
//this loop is pretty simple, and I've used it many times, and it basically sums the marks of the chosen student to then get divided by the length of the array to give us the gpa
for (int i= 0; i <names.length; i ) {
if (Objects.equals(nameSum, names[i])) {
for (int j =0; j<marks[i].length; j ) {
sum = marks[i][j];
}
}
}
double avg = (sum/5);
System.out.println("The student's GPA is " avg);
}
public void findAverage() {
int y = -1;
int sum;
//in the line below I made a new array to hold the values that the loop will create from teh old array
double[] newMarks= new double[marks.length];
//the loop will make new values to then put in a new array that hold 5 summations of the old secondary arrays
for (int i= 0; i <marks.length; i ) {
y ;
sum = 0;
for (int j =0; j<marks[i].length; j ) {
sum = marks[i][j];
}
double gpa = sum/5;
newMarks[y] = gpa;
}
double sum2=0;
for (int i =0; i< newMarks.length; i ) {
sum2 = newMarks[i];
}
double avg = sum2/ newMarks.length;
System.out.println("The Average GPA of the class is " avg);
}
public void lowestGpa() {
int y = -1;
int sum;
//in the line below I made a new array to hold the values that the loop will create from teh old array
int[] newMarks= new int[marks.length];
//the loop will make new values to then put in a new array that hold 5 summations of the old secondary arrays
for (int i= 0; i <marks.length; i ) {
y ;
sum = 0;
for (int j =0; j<marks[i].length; j ) {
sum = marks[i][j];
}
newMarks[y] = sum;
}
int newSum =newMarks[0];
int num=0;
//in this loop I can find the lowest gpa of the students
for (int z=0; z< newMarks.length; z ) {
if (newMarks[z] < newSum) {
newSum = newMarks[z];
num = z;
}
}
String lowName = names[num];
double newGpa =newSum/5;
System.out.println("The lowest gpa is " newGpa " and the name of the student who got it is " lowName "\n");
}
public void highestGpa() {
int y = -1;
int sum;
//in the line below I made a new array to hold the values that the loop will create from teh old array
int[] newMarks= new int[marks.length];
//the loop will make new values to then ut in a new array that hold 5 summations of the old secondary arrays
for (int i= 0; i <marks.length; i ) {
y ;
sum = 0;
for (int j =0; j<marks[i].length; j ) {
sum = marks[i][j];
}
newMarks[y] = sum;
}
String highName = "";
int oldGpa =newMarks[0];
int z;
//in this loop I can find the highest gpa of the students
for (z=0; z< newMarks.length; z ) {
if (newMarks[z] > oldGpa) {
oldGpa = newMarks[z];
}
highName= names[z];
}
double newGpa =oldGpa/5;
System.out.println("The highest gpa is " newGpa " and the student who got it is " highName "\n");
}
}
I was wondering if you could help me fix the removeStudent
method. I think the problem is probably in lines 137 to 146.
CodePudding user response:
Make question to a small area.
I will test remove like this:
public class Main {
public static String[] removeOne(String[] array1, int pos){
String[] array2 = new String [array1.length - 1];
for (int i = 0, j = 0; i < array1.length; i ) {
if (i == pos) {
continue;
}
array2[j ] = array1[i];
}
return array2;
}
public static int[][] remove2DOne(int[][] array1, int pos){
//Do it your self
//int[][] array2 =null;
return array2;
}
public static void main(String[] args) {
String[] names= {"Nadim", "Sarah","Alfred","Hala","Abed"};
int[][] marks= {
{90, 45, 67, 23, 35},
{100, 100, 100, 100, 100},
{79, 83, 86, 89, 99},
{80, 88, 50, 50, 50},
{81, 85, 88, 91, 90}
};
System.out.println("Hello world!");
String find1="Alfred";
int pos = -1;
for (int i=0;i< names.length;i ){
if (find1.equals(names[i])) {
pos=i;
System.out.println("find " find1 " at " i "<-- " names[i]);
}
}
if (pos != -1) names = removeOne(names, pos);
for(String s:names){
System.out.println(s);
}
if (pos != -1) marks = remove2DOne(marks, pos);
show2D(marks);
}
}
ANS:
public static int[][] remove2DOne(int[][] array1, int pos){
int[][] array2 = new int[array1.length - 1][array1[0].length];
for (int i = 0, j = 0; i < array1.length; i ) {
if (i == pos) {
continue;
}
array2[j ] = array1[i];
}
return array2;
}
static void show2D(int[][] array){
for(int i=0;i< array.length;i ){
for (int j=0;j<array[i].length;j ){
System.out.print(array[i][j]);
System.out.print(", ");
}
System.out.println();
}
}
CodePudding user response:
You need to learn how to debug your code.
You specifically asked for help with method removeStudent
so my answer relates only to that method.
When I run the code in your question, I get the following exception
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4
This is because this nested for
loop is wrong:
int count =0;
for (int i =0; i < marks.length; i ) {
if (i != plsWork) {
for (int y =0; y < marks[i].length; y ) {
newMarks[count][y] = marks[i][y];
count ;
}
}
}
count
is the "row" index of array newMarks
and therefore should be incremented in the outer for
loop and not in the inner one. You need to change the above to the following:
int count =0;
for (int i =0; i < marks.length; i ) {
if (i != plsWork) {
for (int y =0; y < marks[i].length; y ) {
newMarks[count][y] = marks[i][y];
}
count ;
}
}
Also, plsWork
will always be 0 (zero), since you replace array names
with array newNames
before you execute the following for
loop:
int plsWork =0;
for ( int i =0; i < names.length; i ) {
if (Objects.equals(nameToRemove, names[i])) {
plsWork = i;
}
}
names
no longer contains nameToRemove
. Also note that once you have found nameToRemove
, you can exit the for
loop. You need to move the following lines of code to after the above for
loop:
//making the names array equal to the newNames so when we use the program again the last results will be saved
names = newNames;
System.out.println("The new list of student names is " Arrays.toString(names));
Lastly, after populating newMarks
, you need to replace marks
with newMarks
.
Here is my rewritten version of method removeStudent
:
public void removeStudent(String nameToRemove) {
// making a new shorter array than the names array, so we can save the results
// to it
String[] newNames = new String[names.length - 1];
int namesIndexLess = 0;
// in the lines below are put to copy the names don't math the one selected of
// the old array to the new one
for (String name : names) {
if (!Objects.equals(name, nameToRemove)) {
newNames[namesIndexLess] = name;
namesIndexLess ;
}
}
int plsWork = 0;
for (int i = 0; i < names.length; i ) {
if (Objects.equals(nameToRemove, names[i])) {
plsWork = i;
break;
}
}
// making the names array equal to the newNames so when we use the program again
// the last results will be saved
names = newNames;
System.out.println("The new list of student names is " Arrays.toString(names));
double[][] newMarks = new double[marks.length - 1][marks[0].length];
int count = 0;
for (int i = 0; i < marks.length; i ) {
if (i != plsWork) {
for (int y = 0; y < marks[i].length; y ) {
newMarks[count][y] = marks[i][y];
}
count ;
}
}
marks = newMarks;
}
What happens if the user enters the name of a student that does not exist in names
? Should you ignore it? Should you throw an exception? It appears that the student name serves as a unique identifier. Hence, in method addStudent
, should you check whether a duplicate name is being added?