Blue Pelican Java Textbook Lesson 17 Project AddEmUp - java

So my teacher gave me an assignment to do (will be shown below) and I tried to do it but just could not figure it out, here's the assignment:
Consider the following program that allows something like 8 + 33 + 1,345 + 137 to be entered as String input from the keyboard, A Scanner object then uses the plus signs (and any adjoining white space) as delimiters and produces the sum of these numbers (1523).
import java.io.*;
import java.util.*;
public class Tester
{
public static void main(String args[])
{
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1,345 +137 : ");
String s = kb.nextLine( ); //Best to store in a String and then create a new Scanner
//object; otherwise, it can get stuck waiting for input.
Scanner sc = new Scanner(s);
//Set delimiters to a plus sign surrounded by any amount of white space...or...
// a minus sign surrounded by any amount of white space.
sc.useDelimiter("\\s*\\+\\s*");
int sum = 0;
while(sc.hasNextInt( ))
{
sum = sum + sc.nextInt( );
}
System.out.println("Sum is: " + sum);
}
}
Now modify the program as to allow either plus or minus signs
^^^THAT WAS THE ASSIGNMENT^^^
Here is my source code:
//I can't get it to work if I use subtraction and addition at the same time but they work separately
import java.util.Scanner;
public class AddEmUp {
public static void main(String[] args) {
//Here we create a String
Scanner kb = new Scanner(System.in);
System.out.print("Enter something like 8 + 33 + 1345 - 137 : ");
String s = kb.nextLine();
//Now we convert the String to a scanner because we will be using Scanner methods
Scanner sc = new Scanner(s);
//Creates sum
int sum = 0;
//Does it's magic if it is addition
if (s.contains("+")) {
sc.useDelimiter("\\s*\\+\\s*");
while (sc.hasNextInt()) {
sum = sum + sc.nextInt();
}
}
//Does it's magic if it is subtraction
if (s.contains("-")) {
sc.useDelimiter("\\s*\\-\\s*");
while (sc.hasNextInt()) {
sum = sc.nextInt();
sum = sum - sc.nextInt();
}
}
//Prints the magic
System.out.println("Sum is: " + sum);
}
}
Can anybody help me solve the problem (First comment in my source code)???

I'm going to help you answer this in a way that's (hopefully) consistent with what you've learned so far. Since you haven't learned about arrays yet and are working with a Scanner with a delimiter pattern, we'll have to work around this constraint.
First, for the purposes of a school assignment, we can probably safely assume that your inputs will follow a particular pattern, along the lines of: (number)(operator)(number)(operator)(number)... and so on; additionally, you're probably not worried about input checking (making sure there are no letters/symbols/etc) or negative numbers, so we'll ignore those scenarios. Since you are only dealing with + and -, your delimiters are "\\s*\\+\\s*" and "\\s*\\-\\s*", respectively. Since these values don't change (they are constants), and (in a real program) would be used multiple times in different places, we typically store these in their own final variables:
final String PLUS = "\\s*\\+\\s*"; // by convention, constants in java are named with all caps
final String MINUS = "\\s*\\-\\s*";
Now, let's look at your sample input: 8 + 33 + 1345 - 137. How can you account for mixed operators?
int sum = 0;
Scanner sc = new Scanner(s); // s = "8 + 33 + 1345 - 137"
//What now?
You can still pull this off with one loop, but it will require some intermediate steps.
// start with +
sc.useDelimiter(PLUS);
while(sc.hasNext()){
String temp = sc.next();
}
// first pass, temp = "8"
// first pass, temp = "3"
// first pass, temp = "1345 - 137" (!!!)
In the above example, temp would first be "8" (note that it's a String here), then "33" on the next pass, then "1345 - 137" on the third pass. You would typically use Integer.parseInt() to turn a String to an int, like so:
// start with +
sc.useDelimiter(PLUS);
while(sc.hasNext()){
String temp = sc.next();
sum += Integer.parseInt(temp);
}
// first pass, temp = "8"
// first pass, temp = "3"
// first pass, temp = "1345 - 137", code breaks at Integer.parseInt(temp)
However, this code breaks on the third pass, because "1345 - 137" is clearly not an integer value. This is where storing the value in temp comes into play; you can use a nested loop to evaluate subtraction portions of your expression! You were on the right track with checking for + and - in the input, and here is a more appropriate spot to use it:
// start with +
sc.useDelimiter(PLUS);
while(sc.hasNext()){
String temp = sc.next();
// check if there are - signs in temp
if(temp.contains("-")){
// if there are, evaluate the subtraction expression
// for this example, temp = "1345 - 137"
Scanner sc2 = new Scanner(temp);
sc2.useDelimiter(MINUS);
int diff = sc2.nextInt(); // diff = 1345
while(sc2.hasNext()){
diff -= sc2.nextInt(); // diff = 1345 - 137 = 1208
}
sum += diff; // adds the result to the sum
} else {
sum += Integer.parseInt(temp); // there is no - sign, so skip ahead and just add to the sum
}
}
You'll notice I didn't check if the input contains a + sign at the beginning before the loop; this is because I'm assuming that even if you enter something like 1 - 5 - 9, the Scanner will still return at least that whole string when sc.next() is called, which will still go into the inner loop, and the expression will still be evaluated. I haven't used a Scanner in a very long time, so if this assumption is incorrect, you'll have to fix that.

Related

How do you make it so that when you enter a number it puts a space between each integer

import java.util.Scanner;
public class Digits {
public static void main(String[] args) {
/*
*
count = 1
temp = n
while (temp > 10)
Increment count.
Divide temp by 10.0.
*/
//Assignment: fix this code to print: 1 2 3 (for 123)
//temp = 3426 -> 3 4 2 6
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int count = 1;
int temp = input.nextInt();
while(temp >= 10){
count++;
temp = temp / 10;
System.out.print(temp + " ");
}
}
}
Need help fixing code.
Example: when you type 123 it becomes 1 2 3.
Your code is dividing by ten each time, that could be used to print the value in reverse. To print it forward you need a bit more math involving logarithms. Sometime like,
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
int temp = input.nextInt();
while (temp > 0) {
int p = (int) (Math.log(temp) / Math.log(10));
int v = (int) (temp / Math.pow(10, p));
System.out.print(v + " ");
temp -= v * Math.pow(10, p);
}
Alternatively, read a line of input. Strip out all non digits and then print every character separated by a space. Like,
String temp = input.nextLine().replaceAll("\\D", "");
System.out.println(temp.replaceAll("(.)", "$1 "));
Most of your code is correct, and what you are trying to do is divide by 10 and then print out the value - this probably should have been a modulus operation % to get the remainder of the operation and print that out - but a nice way of thinking about it.
Nevertheless.
You can just use a string and then split the string on each character
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer: ");
// we know that we are going to get some input - so we will just grab it as a String
// whilst we are expecting an int - we will test this later.
// we are doing this as it makes it easier to split the contents of a string
String temp = input.next();
// is this an int? - we will test this first
try {
// if this parsing fails - then it will throw a java.lang.NumberFormat exception
// see the catch block below
int test = Integer.parseInt(temp);
// at this point it is an int no exception was thrown- so let's go
// through and start printing out each character with a space after it
// the temp(which is a string).toCharArray returns a char[] which we
// can just iterate through and set the variable of each iteration to 'c'
for (char c : temp.toCharArray()) {
// now we are going to print out the character with a space after it
System.out.print(c + " ");
}
} catch (NumberFormatException ex){
// this is not an int as we got a number format exception...
System.out.println("You did not enter an integer. :(");
}
// be nice and close the resource
input.close();
}
Answering solely your question, you can use this one-line code.
int test = 123;
System.out.println(String.join(" ", Integer.toString(test).split("")));
Output is: 1 2 3

Some weird interactions are happening in my code, but I can't find a solution

My code for calculating average is correct but my program wont stop executing they way I want it to. I have to use scanner's functions in order to manipulate the string.
So I wanted to get better at Java and my tutor gave me a problem to solve. The program must accept student id, name of the subject and its marks, all in one string, and then calculate the average marks for this id. The format of the sting is "123456 math 5.5 physics 6.5 end" where the 6 digit number is the id and "end" is what makes the program stop waiting for numbers and calculate them.
ID is a 6 digit number from 0 to 9 which if it is 000000 the program must terminate.
"End" is stopping the entry but not the loop, but "000000" ends the loop.
In my code everything works fine but in order for the variables I use to reset I must type two times the word "end" and if I want to stop the loop I must type "000000" twice which is clearly not what I want. Can you point out my mistakes?
My teacher suggested to use Scanner's functions in order to get what I want. Is this problem something I cannot solve because of they way these functions work?
package averagemarks;
import java.util.*;
class AverageMarks {
public static void main(String args[]) {
String s = "123456 pr1 6.2 pr2 7.3"; //string input format
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\\s+"); //space to split string tokens
sc.useLocale(Locale.US); //with that it can recognise float numbers
int count = 0;
double sum = 0.0;
String AM; //6 numbers from 0-9 consists the student id
System.out.println("Give string: ");
while(sc.hasNext()) {
String str = sc.next();
if (sc.hasNext("[0-9]{6}")) { //this is where i check for the id which if it is 000000 it must terminate the loop
AM=str;
System.out.println("AM: " + AM);
if (AM.equals("000000")) break;
} else if(sc.hasNext()== false) { //string must end with an end if user does not end it with it i must inform him
System.out.println("Data format error.");
//return;
} else if(sc.hasNextFloat()){ //this is where i gather data for the result
sum += sc.nextFloat();
count++;
} else if(sc.hasNext("end")){ //end means that you gonna calculate all the numbers till that point then reset for another student
System.out.println("Average is " + sum / count);
count = 0;
sum = 0.0;
}
}
}
}
"In my code everything works fine"
Well, it does not!
With the line String str = sc.next(); you read away required data.
You should put it in the end to read the course name away.
while(sc.hasNext()) {
// check student id
if (sc.hasNext("[0-9]{6}")) {
AM=sc.next(); // read student number
System.out.println("AM: " + AM);
if (AM.equals("000000")) break;
}
// check if line ends prematurely --> error
else if(sc.hasNext()== false) {
System.out.println("Data format error.");
//return;
}
// check for a float
else if(sc.hasNextFloat()){
sum += sc.nextFloat(); // read the float
count++;
}
// check for "end"
else if(sc.hasNext("end")){
String endStr = sc.next(); // read "end"
System.out.println("Average is " + sum / count);
count = 0;
sum = 0.0;
}
// all other not yet considered strings (e.g. a course)
else {
String course = sc.next(); // read course
}
}
Try this:
String AM = null; //6 numbers from 0-9 consists the student id
System.out.println("Give string: ");
String str = null;
while(sc.hasNext()) {
if (sc.hasNext("[0-9]{6}"))
{
str = sc.next("[0-9]{6}");
AM = str;
System.out.println("AM: " + AM);
if (AM.equals("000000")) break;
}
else if(sc.hasNext()== false) {
System.out.println("Data format error.");
//return;
}
while(sc.hasNextDouble()){
sum += sc.nextDouble();
count++;
}
if(sc.next().equals("end")){
System.out.println("Average is " + sum / count);
count = 0;
sum = 0.0;
}
}
I did not check if your sc.hasNext()==false works, but everything else seems to working properly. Only type end once to go to next option, "000000" to end entire program. I changed the next float to next double because you had sum declared as a double and put it into a loop so it finds all the next doubles. I moved all the next operations into the conditions as well. Remember that .next() moves to the next one. Your old code with sc.hasNext("end") did not move the cursor at all. Let me know if something is off or if you have a question!

Java-How to Display Numbers 5 Times Before a New Line

So I know I have to get the remainder in order for this to work. However, it works perfectly except for the first line where it gives me 6 instead of 5 for the first line. I think this is happening because 0 is considered a multiple of 5, but I am not really sure of how to get around this. I looked at How to display 5 multiples per line? but I am having trouble seeing how to fix my code using that as it doesn't appear like they had the first line being messed up issue. For example, if I enter 17 into the positive number it gives 6 numbers for the first line and then 5 for the rest. Then it gives the remaining ones which is what I want. For the average part you can type anything as I am going to work on that later. So the format should be something like this:
4.50, 5.56, 2.73, 8.59, 7.75,
...
5.34, 3.65,
Here is my code and thanks for the help:
import java.text.DecimalFormat;
import java.util.Scanner;
public class ArrayFun {
public static void main(String[] args) {
ArrayFun a = new ArrayFun();
}
public ArrayFun() {
Scanner input = new Scanner(System.in);
// Get input from the user
System.out.print("Enter a positive number: ");
int limit = input.nextInt();
// Get input from the user
System.out.print("Enter the lower bound for average: ");
double lowerBound = input.nextDouble();
// Generate an array of random scores
double[] allScores = generateRandomArrayOfScores(limit);
// Display scores, wrapped every 5 numbers with two digit precision
DecimalFormat df = new DecimalFormat("0.00");
displayArrayOfScores(allScores , df);
// Calculate the average of the scores and display it to the screen
//double average = calculateAverage(lowerBound , allScores); //
System.out.print("Average of " + limit + " scores ");
System.out.print("(dropping everything below " + df.format(lowerBound) + ") ");
//System.out.println("is " + df.format(average) );//
}
private double[] generateRandomArrayOfScores(int num) {
double[] scores=new double[num];
for (int i=0;i<scores.length;++i) {
double number=Math.random()*100.0;
scores[i]=number;
}
return scores;
}
private void displayArrayOfScores(double[] scores, DecimalFormat format) {
System.out.println("Scores:");
for (int i=0;i<scores.length;++i) {
String num=format.format(scores[i]);
if ((i%5==0)&&(i!=0)) {
System.out.println(num+", ");
}
else{
System.out.print(num+", ");
}
}
System.out.println();
}
}
The problem is indeed the 0, exactly this part (i%5==0)&&(i!=0). Replace this by i%5==4 and it should work. It is because System.out.println(...) makes the new line after printing the string and if you count 0,1,2,3,4,5 those are 6 numbers, because you treat 0 differently. The last number in the groups of 5 has a modulo of 4. (i+1)%5==0 would work too fo course, it is the equivalent. Alternatively you could do an empty System.out.println() using your condition and print the number as the others afterwards.

How to input a lot of data until you type in an invalid number in java

User inputs numbers one by one and then once they type in an invalid number (has to be from 1-200) the program calculates the average of the numbers that were inputted.
I'm just wondering what would the code be for this. I know the one for inputting one piece of data. Example would be:
`Scanner in = new Scanner(System.in);
String numberOfShoes = "";
System.out.println("Enter the number of shoes you want: (0-200) ");
numberOfShoes = in.nextLine();`
this is just an example, but this time I want the user to input a lot of numbers. I know I'm going to include a loop somewhere in this and I have to stop it once it contains an invalid number (using a try catch block).
* I would also like to add that once the user inputs another number it always goes to the next line.
Just use a while loop to continue taking input until a condition is met. Also keep variables to track the sum, and the total number of inputs.
I would also suggest having numberOfShoes be an int and use the nextInt() method on your Scanner (so you don't have to convert from String to int).
System.out.println("Enter your number of shoes: ");
Scanner in = new Scanner(System.in);
int numberOfShoes = 0;
int sum = 0;
int numberOfInputs = 0;
do {
numberOfShoes = in.nextInt();
if (numberOfShoes >= 1 && numberOfShoes <= 200) { // if valid input
sum += numberOfShoes;
numberOfInputs++;
}
} while (numberOfShoes >= 1 && numberOfShoes <= 200); // continue while valid
double average = (double)sum / numberOfInputs;
System.out.println("Average: " + average);
Sample:
Enter your number of shoes:
5
3
7
2
0
Average: 4.25
It added 5 + 3 + 7 + 2 to get the sum of 17. Then it divided 17 by the numberOfInputs, which is 4 to get 4.25
you are almost there.
Logic is like this,
Define array
Begin Loop
Accept the number
check if its invalid number [it is how u define a invalid number]
if invalid, Exit Loop
else put it in the array
End Loop
Add all numbers in your array
I think you need to do something like this (which #Takendarkk suggested):
import java.util.Scanner;
public class shoes {
public void main(String[] args){
int input = 0;
do{
Scanner in = new Scanner(System.in);
String numberOfShoes = "";
System.out.println("Enter the number of shoes you want: (0-200) ");
numberOfShoes = in.nextLine();
input = Integer.parseInt(numberOfShoes);
}while((input>=0) && (input<=200));
}
}
you can use for loop like this
for(::)
{
//do your input and processing here
if(terminating condition satisified)
{
break;
}
}

2 or more digit numbers with delimiters in java

I have this basic program that works pretty well when entering single digit numbers. But when calculating an expression with multiple digits, like 1337 - 456 + 32, the program doesn't move on...it acts likes I did nothing.
It doesn't freeze or output an error message, it just stops.
here's the code:
import java.io.*;
import java.util.*;
public class Tester {
public static void main(String args[]) {
Scanner kb = new Scanner(System.in);
System.out.print("Enter number: ");
String s = kb.nextLine();
Scanner sc = new Scanner(s);
//Set delimiters to a plus sign surrounded by any amount of white space...or...
// a minus sign surrounded by any amount of white space.
sc.useDelimiter("\\s*");
int sum = 0;
int temp = 0;
int intbefore = 0;
if (sc.hasNext("\\-")) {
sc.next();
if (sc.hasNextInt()) {
intbefore = sc.nextInt();
int temper = intbefore * 2;
intbefore = intbefore - temper;
}
}
if (sc.hasNextInt()) {
intbefore = sc.nextInt(); //now its at the sign (intbefore = 5)
}
sum = intbefore;
while (sc.hasNext()) {
if(sc.hasNext("\\+")) { //does it have a plus sign?
sc.next(); //if yes, move on (now at the number)
System.out.println("got to the next();");
if(sc.hasNextInt()) { //if there's a number
temp = sc.nextInt();
sum = sum + temp; //add it by the sum (0) and the sum of (5) and (4)
System.out.println("added " + sum);
}
}
if(sc.hasNext("\\-")) {
sc.next();
System.out.println("got to the next();");
if (sc.hasNextInt()) {
temp = sc.nextInt();
sum = sum - temp; //intbefore - temp == 11
System.out.println("intbefore: " + intbefore + " temp: " + temp);
System.out.println("subtracted " + sum); // subtracted by 11
}
}
}
System.out.println("Sum is: " + sum);
}
}
Help with why this happens and what to do to fix it?
(I'm using netbeans if that helps)
Also, I'm assuming that the input has a space between each number Ex: 123 + -23 - 5
I tried to execute your code and this is what i found.
Suppose your input was 12+1.
Not sc.hasNextInt() will give you 1 which you are assigning to intbefore.
Next the while loop in your code is going to infinite loop cos sc.hasNext() will always be true (and returning 2 in this case ) and it doesn't match the two if conditions inside the while loop thus making your code run in infinite loop. Now go ahead and work on that. All the best.
Try to change the dilimeter as "\\s+" in the first place or just use the default one

Categories

Resources