This is my code, the output will print only the first course, I don't know what is wrong, I'd like some help :(
public class student {
private long student_ID;
private int[] listOfCourses= new int[5];
private double[] Mark=new double[5];
private int numCoures;
public student(long student_ID) {
this.student_ID=student_ID;
}
long getStudentID() {
return student_ID;
}
int getnumCoures(){
return numCoures;
}
void addCourse(int CN) {
for(int i=0 ; i<listOfCourses.length ; i++){
if (listOfCourses[i]==0) {
listOfCourses[i]=CN;
}
}
numCoures++;
}
void addMark(int CN,double M) {
for(int i=0 ; i<listOfCourses.length ; i++) {
if(listOfCourses[i]==CN) {
Mark[i]=M;
}
}
}
void print() {
System.out.println("NAME OF student "+student_ID);
for(int i=0 ; i<numCoures ; i++) {
System.out.println("NAME OF COURSE "+listOfCourses[i]+" MARK "+Mark[i]);
}
}
}
The main method:
public static void main(String[] args) {
student S1 = new student(1000000001);
S1.addCourse(200);
S1.addCourse(201);
S1.addCourse(202);
S1.addMark(200, 100);
S1.addMark(201, 99);
S1.addMark(202, 98);
student S2 = new student(1111111111);
S2.addCourse(300);
S2.addCourse(301);
S2.addMark(300, 70);
S2.addMark(301, 99);
S1.print();
S2.print();
}
Output:
NAME OF student 1000000001
NAME OF COURSE 200 MARK 100.0
NAME OF COURSE 200 MARK 100.0
NAME OF COURSE 200 MARK 100.0
NAME OF student 1111111111
NAME OF COURSE 300 MARK 70.0
NAME OF COURSE 300 MARK 70.0
This is what gave you trouble. The first time you call, you will assign CN to all the courses from 0 to 4.
void addCourse(int CN){
for(int i=0 ; i<listOfCourses.length ; i++){
if (listOfCourses[i]==0) {
listOfCourses[i]=CN;
}
}
numCoures++;
}
Suggestion
void addCourse(int CN){
if (numCoures >= 5) return; // actually, you should throw an exception here
listOfCourses[numCoures] = CN;
numCoures++;
}
Your problem is your addCourse() method:
void addCourse(int CN) {
for (int i = 0; i < listOfCourses.length; i++) {
if (listOfCourses[i] == 0) {
listOfCourses[i] = CN;
}
}
numCoures++;
}
Think about what happens here. When you add the first course, the array is all 0. Hence, the condition listOfCourses[i] == 0 will always yield true and you will fill the whole array with that course number. The next time you try to add a course, the condition will always evaluate to false, hence nothing changes (apart from numCoures).
This also means that you could call addCourse() very often and increase numCoures to some ridiculous number that doesn't have any meaning anymore.
Possible solution
An easy fix would be to actually use numCoures when adding a new course:
void addCourse(int CN) {
if (numCoures < listOfCourses.length) {
listOfCourses[numCoures++] = CN;
}
}
Here, we first check if numCoures is still within the array's bounds. If so, we insert the given course number at index numCoures, which would be 0 the first time around and so on. With the ++ as suffix, numCoures will also be increased after it has been evaluated.
Solution using a HashMap
However, I suggest you replace your plain arrays with one of the many helpful Java collections (unless this is an exercise that explicitly asks you to use plain arrays?). For example, you could go with a HashMap. A map associates a key with a value. This seems to fit your scenario quite well: the course number can be the key and the mark can be the value.
We would declare this as follows:
private HashMap<Integer, Float> courses = new HashMap<>();
Also, don't forget that you will need import java.util.HashMap; at the top of your file.
Your addCourse() method could then become:
void addCourse(int courseNum) {
courses.put(courseNum, null);
}
And addMark() would become:
void addMark(int courseNum, double mark) {
courses.replace(courseNum, mark);
}
If you look up HashMap's put() and replace() methods, you'll notice that we could have used put() in addMark() as well, but I feel like your intent is clearer this way.
Two more methods should now be changed:
int getNumCourses() {
return courses.size();
}
I'll leave the print() to you.
Also, you can now get rid of these three, as they have been replaced by our neat HashMap:
private int[] listOfCourses = new int[5]; // bye bye
private double[] Mark = new double[5]; // cya
private int numCoures; // sayounara
Benefits of using a Map
A student can have more than 5 courses
Your code becomes shorter and easier to read
Your code also becomes less prone to error
Changing or removing courses or grades is easily possible
Additional notes:
You should pay more attention to the names of your classes, variables and methods. I'll point out what I noticed:
The class student should be Student (classes should start with an upper case letter)
The variable Mark should be mark (variables should start with a lower case letter)
The method getnumCoures() should be getNumCourses() )(methods should be camelCase and you mistyped courses)
The variable student_ID and the method getStudentID() could be simplified to id and getID() - we already know that we're dealing with a student!
The addCourse method sets all 5 elements of listOfCourses to the value supplied in the first call. To fix this, you want to exit the loop after setting the value by using a break statement. Otherwise, the code marches through the entire array:
void addCourse(int CN) {
for (int i = 0; i < listOfCourses.length; i++) {
if (listOfCourses[i] == 0) {
listOfCourses[i] = CN;
break;
}
}
numCoures++;
}
There are better ways to accomplish the goals of this program. What happens if a student has more than 5 courses? Look up java.util.List and java.util.Map.
Output is:
NAME OF student 1000000001
NAME OF COURSE 200 MARK 100.0
NAME OF COURSE 201 MARK 99.0
NAME OF COURSE 202 MARK 98.0
NAME OF student 1111111111
NAME OF COURSE 300 MARK 70.0
NAME OF COURSE 301 MARK 99.0
Related
I'm trying to create a method which allows you to choose which index in an array of test scores. It will check what the score is and return a grade for that score. In my getGrade method no matter what the score is it returns "NG".
private double[] scores = new double[3];
private static int[]boundaryVals={80,72,64,60,56,52,48,40,35,30,1,0};
private static String[]grades={"A1","A2","B1","B2","B3","C1","C2","C3","D1","D2","F","NG"};
public String getGrade(int i) {
String grade = "";
for(int x=0;x<boundaryVals.length;x++) {
if(boundaryVals[x] <= i) {
grade = grades[x];
}
}
return grade;
}
Just change the loop exit condition to terminate when a grade has been assigned.
public String getGrade(int i) {
String grade = "";
for(int x=0; x<boundaryVals.length && !grade.equals(""); x++) {
if (boundaryVals[x] <= i) {
grade = grades[x];
}
}
return grade;
}
This is better-structured since it has the loop termination condition in one place, rather than spreading it out by use of "break".
As usual, this is not a hard and fast rule. For more complicated cases, "break" is clearer. It's a matter of taste.
The 'return' from mid-loop, as suggested in comments, is not a bad solution in this particular case either. But I think it's worth pointing out that loop conditions are not limited to simple counting from 0 to N.
Because in the end 0 always smaller/equals to i, so even if 80 is less than i, finally i will de "NG";
Try add the keywords break; after grade = grades[x]; to stop the loop when the condition is true.
break is the keyword you're looking for.
As soon as the break statement is encountered inside a loop, the loop is terminated and it resumes with the next statement.
In your code the loop is never terminated until it gets to the last item in your array, which is 0. And 0 is always smaller than or equal to i. ;)
As title says I need to do the following. But I somehow am getting the wrong answer, perhaps something with the loops is wrong?
And here's what I have coded so far, but it seems to be giving me the wrong results. Any ideas, help, tips, fixes?
import java.util.ArrayList;
public class pro1
{
private String lettersLeft;
private ArrayList<String> subsets;
public pro1(String input)
{
lettersLeft = input;
subsets = new ArrayList<String>();
}
public void createSubsets()
{
if(lettersLeft.length() == 1)
{
subsets.add(lettersLeft);
}
else
{
String removed = lettersLeft.substring(0,1);
lettersLeft = lettersLeft.substring(1);
createSubsets();
for (int i = 0; i <= lettersLeft.length(); i++)
{
String temp = removed + subsets.get(i);
subsets.add(temp);
}
subsets.add(removed);
}
}
public void showSubsets()
{
System.out.print(subsets);
}
}
My test class is here:
public class pro1
{
public static void main(String[] args)
{
pro1s = new pro1("abba");
s.createSubsets();
s.showSubsets();
}
}
Try
int numSubsets = (int)java.lang.Math.pow(2,toSubset.length());
for (int i=1;i<numSubsets;i++) {
String subset = "";
for (int j=0;j<toSubset.length();j++) {
if ((i&(1<<j))>0) {
subset = subset+toSubset.substring(j,j+1);
}
}
if (!subsets.contains(subset)) {
subsets.add(subset);
}
}
where toSubset is the string that you wish to subset (String toSubset="abba" in your example) and subsets is the ArrayList to contain the results.
To do this we actually iterate over the power set (the set of all subsets), which has size 2^A where A is the size of the original set (in this case the length of your string).
Each subset can be uniquely identified with a number from 0 to 2^A-1 where the value of the jth bit (0 indexed) indicates if that element is present or not with a 1 indicating presence and 0 indicating absence. Note that the number 0 represents the binary string 00...0 which corresponds to the empty set. Thus we start counting at 1 (your example did not show the empty set as a desired subset).
For each value we build a subset string by looking at each bit position and determining if it is a 1 or 0 using bitwise arithmetic. 1<<j is the integer with a 1 in the jth binary place and i&(i<<j) is the integer with 1's only in the places both integers have a 1 (thus is either 0 or 1 based on if i has a 1 in the jth binary digit). If i has a 1 in the jth binary digit, we append the jth element of the string.
Finally, as you asked for unique subsets, we check if we have already used that subset, if not, we add it to the ArrayList.
It is easy to get your head all turned around when working with recursion. Generally, I suspect your problem is that one of the strings you are storing on the way down the recursion rabbit hole for use on the way back up is a class member variable and that your recursive method is a method of that same class. Try making lettersLeft a local variable in the createSubsets() method. Something like:
public class Problem1
{
private String originalInput;
private ArrayList<String> subsets;
public Problem1(String input)
{
originalInput = input;
subsets = new ArrayList<String>();
}
// This is overloading, not recursion.
public void createSubsets()
{
createSubsets(originalInput);
}
public void createSubsets(String in)
{
if(in.length() == 1)
{
// this is the stopping condition, the bottom of the rabbit hole
subsets.add(in);
}
else
{
String removed = in.substring(0,1);
String lettersLeft = in.substring(1);
// this is the recursive call, and you know the input is getting
// smaller and smaller heading toward the stopping condition
createSubsets(lettersLeft);
// this is the "actual work" which doesn't get performed
// until after the above recursive call returns
for (int i = 0; i <= lettersLeft.length(); i++)
{
// possible "index out of bounds" here if subsets is
// smaller than lettersLeft
String temp = removed + subsets.get(i);
subsets.add(temp);
}
subsets.add(removed);
}
}
Something to remember when you are walking through your code trying to think through how it will run... You have structured your recursive method such that the execution pointer goes all the way down the recursion rabbit hole before doing any "real work", just pulling letters off of the input and pushing them onto the stack. All the "real work" is being done coming back out of the rabbit hole while letters are popping off of the stack. Therefore, the first 'a' in your subsets list is actually the last 'a' in your input string 'abba'. I.E. The first letter that is added to your subsets list is because lettersLeft.length() == 1. (in.length() == 1 in my example). Also, the debugger is your friend. Step-debugging is a great way to validate that your code is actually doing what you expect it to be doing at every step along the way.
I have a huge problem I can not understant why this part of code throws this exception because I can not see where I get out of my array bound?
I want to derive a polinom with int coeff and positive powers. i save my powers in an array iPower and my coeff in iCoefficient. in my polinom class iMaxPower gives my the highest fower of my polinom.
public int DerivePolinom(Polinom p1, Polinom p2)//operation class
{
int i,count=0;
i=p1.iMaxPower;
while(i>0)
{
if(p1.iPower[i]==1)// here is my exception!
{
p2.iPower[i]=1;//I know it does not derive my polinom
p2.iCoefficient[i]=p1.iCoefficient[i];
count++;// use this to know the nr of the result polinom terms
}
i++;
}
return count;
}
int iDegreeMax=0;//main class
System.out.print("Enter the polinom: number of terms-power-coefficient \n");
Polinom p1 = new Polinom();//create my polinom object
iDegree=sc.nextInt();//read the numbers of terms
p1.readPolinom(iDegree);//read my polinom
p1.printPolinom(p1,iDegree);
Operation o = new Operation();//create operation object
Polinom p2 = new Polinom();//we create another polinom object to pun the result in
iDegreeMax=o.DerivePolinom(p1,p2);
System.out.print("\nThe derivation of the polinom is: ");
p2.printPolinom(p2,iDegreeMax);
In this loop, there is nothing to make the loop exit,
so the value of i will keep increasing,
until eventually it goes beyond the bound of p1.iPower.
while(i>0)
{
if(p1.iPower[i]==1)// here is my exception!
{
p2.iPower[i]=1;//I know it does not derive my polinom
p2.iCoefficient[i]=p1.iCoefficient[i];
count++;// use this to know the nr of the result polinom terms
}
i++;
}
You need to add a condition either inside the while statement itself,
or inside the loop body to break out of it. This might work for example:
while (i > 0 && i < p1.iPower.length)
This is a homework question so preferably I would like to write as much code as possible, just need a pointer.
I have a class called Sandwich that has a Method to set a main Ingredient and a few other things -
public class Sandwich {
private String mainIngredient, bread;
String getMainIngredient(){
return mainIngredient;
}
void setMainIngredient(String mainIng){
mainIngredient = mainIng;
}
void setBread(String dough){
bread = dough;
}
void setPrice(double cost){
price = cost;
}
Now in another class TestSandwich I've initialized an Array, as part of the question;
Sandwich[] sandwiches = new Sandwich[5];
Now what I need to do is loop through and assign a value to mainIngredient and bread each time.
I think I would want to do something along the lines of this but I'm not really sure how to do it correctly.
for(int i = 0; i < 5; i++){
System.out.println("Insert a main ingredient");
String userInput = sc.next();
sandwiches[i].setBread(userInput);
System.out.println("Insert a bread");
userInput = sc.next();
sandwiches[i].setMainIngredient(userInput);
System.out.println(sandwiches[i].getMainIngredient());
System.out.println("");
}
The main issue is - sandwiches[i].setMainIngredient(userInput);
Im not really experienced with arrays and methods such as these so any help with the correct syntax would be great.
Thanks
Sandwich[] sandwiches = new Sandwich[5]; creates an array of 5 null references.
You need to initialise each element yourself; in your loop write
sandwiches[i] = new Sandwich();
else you'll get NullPointerExceptions. Once you've done that you can call the setting methods as you currently do. Going forward, you could declare a two argument constructor taking the bread and main ingredient as arguments. That's better style since (i) you avoid setters and (ii) the object being in an ill-defined state between construction and use.
Sandwich[] sandwiches = new Sandwich[5];
This allocates an array to hold 5 sandwiches, but it doesn't create any sandwiches. Just the array. You're on the right track to create the sandwiches in a loop.
When you write this loop, instead of iterating until 5, it's better to use sandwiches.length, so that if you want 10 instead of 5 sandwiches, you can change the number in one place instead of 2. It will be safer and less error-prone:
for (int i = 0; i < sandwiches.length; ++i) {
// TODO: get the ingredients from user
// ready to create the sandwich, yum yum
Sandwich sandwich = new Sandwich();
sandwich.setBread("...");
sandwich.setMainIngredient("...");
sandwiches[i] = sandwich;
}
I'm stuck on how to write a delete method for a menu (object orientation) program I am writing. The menu gives the user the option to delete the last name entered on the program. I'm completely stuck on this part! Would be greatly appreciated if you guys/gals could show me a simple delete method!
Many Thanks!
This is my code so far for Adding a Name:
public static int addOne(String theArray[], int location, String theName, int noofvalues)
{
int step;
if(noofvalues == 0)
{
theArray[0] = theName;
noofvalues++;
}
else
{
for(step = noofvalues - 1; step >= location; step--)
{
theArray[step + 1] = theArray[step];
}
theArray[location] = theName;
noofvalues++;
}
return noofvalues;
}
Since it looks like homework, I won't provide any code at all (otherwise, I would solve the homework and you won't learn anything), only ideas an possibly an algorithm to do it.
Store the last name inserted by the user in a variable. Let's say, this variable is lastInsertedName.
Go through all the elements in your array and search this String in it. When you find lastInsertedName in the array, store the index in a variable, let's say indexFound and stop the loop.
If indexFound is greater or equals than 0:
Move all the elements starting at indexFound in the array one position back.
Decrease the variable that acts as the size of your array.
Use List:
public static int addOne(List names, int location, String theName, int noofvalues)
{
names.add(location, theName);
return names.size();
}
public static void deleteOne(List names, int location){
names.remove(location);
}