Random Math Question Generator not following while loop - java

I'm a new java coder getting into it doing a project. I coded it how i believe the system would execute it and yet it doesn't seem to be following the While loops requirements. I want it to generate random number, do a random operation, then ask the user for an answer. The answer must be not decimal and the random numbers must be below 10 to make the questions easier as its for a lower target audience. I'm kind of stuck now on this piece. Apologies if this doesn't make sense as i say it is a first attempt for me.
import java.util.Random;
import java.lang.Math;
import java.util.Scanner;
public class RandomisedQuestions{
public static void QuestionGenerator(){
Random r = new Random();
Scanner s = new Scanner(System.in);
int intA = 0;
int intB = 0;
char operator ='?';
double value = 1.2;
for (int i = 0; i < 3; i++) {
intA = (int)(10.0 * Math.random());//the (int) forces the number to be an int
intB = (int)(10.0 * Math.random());
if (intA <= 0 && intB <= 0){
intA = (int)(10.0 * Math.random());//the (int) forces the number to be an int
intB = (int)(10.0 * Math.random());
System.out.println(intA + intB);
}
while ((value % 1) !=0 && value > 1){//Runs while value is not whole
switch (r.nextInt(4)){
case 0: operator = '+';
value = intA+intB;
break;
case 1: operator = '-';
value = intA-intB;;
break;
case 2: operator = '*';
value = intA*intB;;
break;
case 3: operator = '/';
value = intA/intB;;
break;
default: operator = '?';
}
//System.out.println(operator);
}
System.out.println(intA +""+ operator +""+ intB);
System.out.println("Enter the answer");
int uGuess = s.nextInt();
if (uGuess == value){
System.out.println("Correct");
}
else{
System.out.println("Incorrect");
}
}
}
}

It's better to use ThreadLocalRandom.nextInt to generate your numbers:
// At the start of your program initialize the generator:
ThreadLocalRandom r = ThreadLocalRandom.current();
// Later use it:
do {
intA = ThreadLocalRandom.nextInt(1, 10);
intB = ThreadLocalRandom.nextInt(1, 10);
switch (r.nextInt(4)) {
case 0: operator = '+';
value = intA + intB;
break;
case 1: operator = '-';
value = intA - intB;
break;
case 2: operator = '*';
value = intA * intB;
break;
case 3: operator = '/';
value = (double)intA / intB;
break;
default: operator = '?';
}
} while (value != (int)value || value <= 1);
Also note the conversion to double in division case, otherwise the division will be performed for integer types.

Related

Best way to change operators in string to their opposite

I have a string like: value += 5 * 3 - (2 / 4) for example.
Now I must change all operators to their opposite, so:
+ to -
- to +
* to /
/ to *
My problem is when I use replaceAll() function
First time:
string.replaceAll("+", "-"); I become: value -= 5 * 3 - (2 / 4)
Second time:
string.replaceAll("-", "+"); I become: value += 5 * 3 + (2 / 4)
but it's need to be: value -= 5 * 3 + (2 / 4)
How can I achive that?
You could create a Map with the Characters to replace and iterate through the String like this:
public static void main(String[] args) {
Map<Character, Character> replacers = new HashMap<>();
replacers.put('+', '-');
replacers.put('-', '+');
String value = "value += 5 * 3 - (2 / 4)";
StringBuilder out = new StringBuilder();
for (char c : value.toCharArray()) {
out.append(replacers.getOrDefault(c, c));
}
System.out.println(out.toString());
}
This will print out:
value -= 5 * 3 + (2 / 4)
Why not just loop through string char-by-char and replace single letter at a time to avoid such chaos?
public String revert(String expression){
char[] temp = expression.toCharArray();
for(int i = 0; temp.length> i; i++){
switch(temp[i]){
case '/':
temp[i] = '*';
break;
case '*':
temp[i] = '/';
break;
case '-':
temp[i] = '+';
break;
case '+':
temp[i] = '-';
break;
}
}
return new String(temp);
}
You could first replace your symbols (+,-,...) to some different ones that cannot be present in your expression e.g. +->A, -->B, ... and than all As to -, Bs to +, ... .
Other option is creating array of chars from your string and than iterate this array invert your symbols in situ. and than create String again.
I think a simple loop will work;
String exp="YOUR EXPRESSION HERE";
String newStr="";
//loop through the string
for(int i=0;i<exp.length();i++)
{
char ch=exp.charAt(i);//extract a charcter
switch(ch)
{
case '+':
newExp+='-';// replace + with -
break;
case '-':
newStr+='+';// and - with +
break;
case '*';
newStr+='/'// divide with *
break;
case '/'
newStr+='*';// multiply with /
break;
default:
newStr+=ch;// leave it as it is
}
}
You are probably better off just looping through the values, perhaps in a char array.
String val = "value += 5 * 3 - (2 / 4)";
char[] cArray = val.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cArray.length; i++) {
if (cArray[i] == '+') {
sb.append("-");
} else if (cArray[i] == '-') {
sb.append("+");
// repeat for others
} else {
sb.append(cArray[i]);
}
}
Output:
value -= 5 * 3 + (2 / 4)

How do i convert an if-else statement to a switch statement

I have this program of rolling dice by 1000000 and finding the number of 1's, 2's, 3's, 4's, 5's, 6's`but i need to make a switch statement as well. Im having trouble using the scanner input
import java.util.Random;
public class DiceRoll_NP {
public static void main(String[] args) {
Random rand = new Random();
final double NUMBER_OF_ROLLS = 1000000.0;
int x = rand.nextInt();
// System.out.println(x);
int ones = 0, twos = 0, threes = 0, fours = 0, fives = 0, sixes = 0;
for (int i = 1; i <= NUMBER_OF_ROLLS; i = i + 1) {
int y = rand.nextInt(6) + 1;
if (y == 1) ones++;
else if (y == 2) twos++;
else if (y == 3) threes++;
else if (y == 4) fours++;
else if (y == 5) fives++;
else if (y == 6) sixes++;
System.out.print(y + " ");
}
System.out.printf("\nOnes: %.2f%%\n", 100 * ones / NUMBER_OF_ROLLS);
System.out.printf("Twos: %.2f%%\n", 100 * twos / NUMBER_OF_ROLLS);
System.out.printf("Threes: %.2f%%\n", 100 * threes / NUMBER_OF_ROLLS);
System.out.printf("Fours: %.2f%%\n", 100 * fours / NUMBER_OF_ROLLS);
System.out.printf("Fives: %.2f%%\n", 100 * fives / NUMBER_OF_ROLLS);
System.out.printf("sixes: %.2f%%\n", 100 * sixes / NUMBER_OF_ROLLS);
}
}
This i what i have so far. When i run it, nothing comes up
import java.util.Random;
public class DiceRoll_Switch {
public static void main(String[] args) {
Random rand = new Random();
int ones = 0, twos = 0, threes = 0, fours = 0, fives = 0, sixes = 0;
int y = rand.nextInt(6) + 1;
for (int i = 1; i <= 1000000; i = i + 1)
switch (y){
case 1: ones++;
break;
case 2: twos++;
break;
case 3: threes++;
break;
case 4: fours++;
break;
case 5: fives++;
break;
case 6: sixes++;
break;
In the early days of programming, the goto statement was heavily used. It works like this:
if ( true )
goto label;
System.out.println("A");
label:
System.out.println("B");
The above code would jump to the label, skipping printing the A. It's pretty simple.
Now, why did I mention this? Here's an example of an if statement:
if ( y == 1 )
System.out.println("It is 1");
else
System.out.println("It is not 1");
and here's how it works using goto:
if ( y != 1 )
goto not_1;
// this is the 'then' part:
System.out.println("It is 1");
goto done; // we don't want to run the 'else' part!
not_1:
// this is the 'else' part
System.out.println("It is not 1");
done:
If you understand this, then a switch statement won't be any trouble.
A switch statement looks like this:
switch (y) {
case 1: ones++; break;
case 2: tows++; break;
default: System.out.println("Unexpected number of eyes: " + y);
}
It compares the value of y with all the values after the case, and if it is a match, starts executing the code at that case. The break indicates that that case is done. The default 'case' gets executed when none of the cases is a match.
And here's how it basically works using goto:
if ( y == 1 ) goto case_1;
if ( y == 2 ) goto case_2;
// here comes the default:
default:
System.out.println("Unexpected number of eyes: " + y);
goto switch_done;
case_1:
ones++;
goto switch_done; // this is the 'break' statement.
case_2:
twos++;
goto switch_done;
switch_done: // end of the switch.
I hope this makes things a bit more clear as to how it works!
That said, you're better off using an array:
int eyes[] = new int[] { 0,0,0,0,0,0 };
for ( int i = 1; i <= NUMBER_OF_ROLLS; i++ )
{
int y = rand.nextInt(6) + 1;
eyes[y] ++;
}
This also makes your printing much shorter:
for ( int i = 0; i < eyes.length; i ++ )
System.out.printf( (i+1) + ": %.2f%%\n", 100 * eyes[i] / NUMBER_OF_ROLLS );
You are basically doing the same thing for each y, and you should want to write as little code as possible: it is easier to maintain and to understand, and, there is less chance of bugs.
It's very similar. These two are pretty much doing the exact same thing:
int x = 2;
if(x == 1) {
System.out.println("1");
}
else if(x == 2) {
System.out.println("2");
}
else {
System.out.println("None of the above");
}
int x = 2;
switch(x) {
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
default:
System.out.println("None of the above");
break;
}
A switch statement consists in:
switch (y) {
case 1:
ones++;
break;
case 2:
twos++;
break;
...
}
and so on, where the value inside the parenthesis is the variable name you want to check, and the number after "case" is the cases it may happen. You MUST put a break after your instruction is over to tell the program it can exit the switch statement after he founds the correct one and stops executing. Otherwise, if you don't put the break; command in the "case 1" block, it'll keep executing every line until it finds a break, and both "ones" and "twos" will be added

String index out of range: 2.Doing calculation in Postfix expression style.

I'm making a RPN calculator, I have done the part of converting infix to postfix, now I want to evaluate the expression in postfix.
example:
converting from ((3 + 5 1)=8) 14 to 3 5 1 +8 = 14 (I have done that). now evaluating the latter expression.
The instructions I have:
Given a postx expression v 1:::v n,
where v i is either an operand or an operator,
the following algorithm evaluates the expression. A helper string, temp2, is
used during the calculation.
i = 1
while i<= n
if v_i is an operand: Push v_i to tmp2.
if v_i is
an operator: Apply v_i to the top two elements of tmp2. Replace
these by the result in tmp2.
i = i + 1
Output result from tmp2.
My code:
static int eval(String postfix) {
int result = 0;
String temp2 = "";
int num1, num2;
char operator;
for (int i = 0; i < postfix.length(); i++) {
char M = postfix.charAt(i);
// if v_i is an operand: Push v_i to tmp2.
if (Character.isDigit(postfix.charAt(i))) {
temp2 = M + temp2;
}
/*
* if v_i is an operator: Apply v_i to the top two elements of tmp2.
* Replace these by the result in tmp2.
*/
if (postfix.charAt(i) == '+' || postfix.charAt(i) == '-' || postfix.charAt(i) == '*'
|| postfix.charAt(i) == '/') {
temp2 = M + temp2.substring(2);
num1 = Character.getNumericValue(temp2.charAt(temp2.length() - 1));
operator = postfix.charAt(i);
num2 = Character.getNumericValue(temp2.charAt(temp2.length() + i - 1));
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
}
}
}
return result;
}
I get
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at:
num2 = Character.getNumericValue(temp2.charAt(temp2.length() + i - 1));

String index out of range when accessing chars in a String

I'm trying to make an RPN calculator. I have done the conversion from infix to postfix, now I want to evaluate the converted expression. When I enter any expression I get error
String index out of range: 1.
Here's my code with what I'm supposed to do in the program:
static int eval(String postfix) {
int result = 0;
String temp2 = "";
int num1, num2, OPS;
char operator;
String delete = "";
for (int i = 0; i < postfix.length(); i++) {
char M = postfix.charAt(i);
// if v_i is an operand: Push v_i to tmp2.
if (Character.isDigit(postfix.charAt(i))) {
temp2 = M + temp2;
}
/*
* if v_i is an operator: Apply v_i to the top two elements of tmp2.
* Replace these by the result in tmp2.
*/
if (postfix.charAt(i) == '+' || postfix.charAt(i) == '-' || postfix.charAt(i) == '*'
|| postfix.charAt(i) == '/') {
temp2 = M + temp2.substring(2);
}
while (postfix.charAt(0) != '0') {
num1 = Character.getNumericValue(temp2.charAt(temp2.length()-1));
delete = delete.substring(0,i);
operator = postfix.charAt(i);
num2 = Character.getNumericValue(temp2.charAt(temp2.length()+i));
//Integer.parseInt(postfix.substring(0,i));
result = num1 + num2;
result = num1 - num2;
result = num1 * num2;
result = num1 / num2;
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
}
}
if (temp2.length() != 0) {
temp2 = result + temp2;
}
}
return result;
}
I get the error in this part:
while (postfix.charAt(0) != '0') {
num1 = Character.getNumericValue(temp2.charAt(temp2.length()-1));
delete = delete.substring(0,i);
operator = postfix.charAt(i);
num2 = Character.getNumericValue(temp2.charAt(temp2.length()+i));
//Integer.parseInt(postfix.substring(0,i));
As you can see, I have tried some different string manipulation but they're all incorrect.
My supervisor said something about reading the string from backwards or the last string or something, But I never understood what they meant. Thanks for any help in advance
temp2.charAt(temp2.length()+i)
You are accessing a character of the string with charAt. However temp2 contains temp2.length() characters. Hence you can acces them from index 0 to temp2.length() - 1. Hence accessing the character at position temp2.length()+i is out of range... (for i > 0 !!)
Take a look at your previous one, temp2.charAt(temp2.length()-1).
Here you accessed the last character of the string (at index temp2.length()-1). Any access with a greater index will result in an index out of range.
EDIT : The stop condition of your while loop is while (postfix.charAt(0) != '0'). In the loop you never change the postfix string. Hence if the condition is met (first character of postfix is not '0') you'll have an infinite loop. Hence you'll never reach the return statement.
Change this line
Character.getNumericValue(temp2.charAt(temp2.length()+i));
to
Character.getNumericValue(temp2.charAt(temp2.length()+i-1));

Convert arithmetic string into double in Java

I have a program where the user inputs 6 doubles, and the program outputs every combination of operators that can go in-between the doubles as 1024 separate strings. Here are the first two results if the user inputed 14,17,200,1,5, and 118:
"14.0+17.0+200.0+1.0+5.0+118.0"
"14.0+17.0+200.0+1.0+5.0-118.0"
What I want to do is perform the arithmetic according to the order of operations. Each double is stored as a variable a through f and each operator in-between these variables is stored as a char a_b through e_f. So:
double a, b, c, d, e, f;
char a_b, b_c, c_d, d_e, e_f;
My first thought was to write the code like this:
public double operateGroup() {
value = 0;
switch (a_b) {
case '+':
value += a + b;
break;
case '-':
value += a - b;
break;
case '*':
value += a * b;
break;
case '/':
value += a / b;
break;
default:
break;
}
switch (b_c) {
case '+':
value += c;
break;
case '-':
value += -c;
break;
case '*':
value *= c;
break;
case '/':
value /= c;
break;
default:
break;
}
switch (c_d) {
case '+':
value += d;
break;
case '-':
value += -d;
break;
case '*':
value *= d;
break;
case '/':
value /= d;
break;
default:
break;
}
switch (d_e) {
case '+':
value += e;
break;
case '-':
value += -e;
break;
case '*':
value *= e;
break;
case '/':
value /= e;
break;
default:
break;
}
switch (e_f) {
case '+':
value += f;
break;
case '-':
value += -f;
break;
case '*':
value *= f;
break;
case '/':
value /= f;
break;
default:
break;
}
return value;
}
But this doesn't work because it is the same as doing (a O b) O c) O d) O e) where O is any arbitrary operator. Any tips?
Since there are no parentheses, a trivial approach will work:
Go through the list once to process multiplications and divisions
When an operator between X and Y is * or /, replace X by X*Y or X/Y, and remove Y; also remove the operator
Now go through the list again, this time processing additions and subtractions in sequence.
To implement this approach, define two lists - the list of N Doubles, and N-1 operators, and implement the calculation as follows:
ArrayList<Double> vals = ...
ArrayList<Integer> ops = ... // 1=+, 2=-, 3=*, 4=/
for (int i = 0 ; i < ops.Count ; i++) {
int op = ops.get(i);
if (op == 3 || op == 4) {
if (op == 3) {
vals.set(i, vals.get(i) * vals.get(i+1));
} else {
vals.set(i, vals.get(i) / vals.get(i+1));
}
ops.remove(i);
vals.remove(i+1);
i--;
}
}
double res = vals.get(0);
for (int i = 0 ; i != ops.Count ; i++) {
if (op == 1) {
res += vals.get(i);
} else {
res -= vals.get(i);
}
}
If you need the operators' and operands' information, you should build a Parse Tree (this has been asked before).
If you are only interested in the result, you can evaluate the String directly:
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Eval {
public static void main(String[] args) throws Exception {
ScriptEngineManager s = new ScriptEngineManager();
ScriptEngine engine = s.getEngineByName("JavaScript");
String exp = "14.0+17.0+200.0+1.0+5.0-118.0";
System.out.println(engine.eval(exp));
}
}
Output:
119.0
I would say you should parse it into a tree and then walk the tree to evaluate. Numbers are leaf nodes and operators are parents.

Categories

Resources