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.
Related
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.
Why is the output "ADC" and where the D came from ? Also, what is the goal of the default and continue commands in this code?
char x = 'A';
while(x != 'D') {
switch(x) {
case 'A':
System.out.print(x); x = 'D';
case 'B':
System.out.print(x); x = 'C';
case 'C':
System.out.print(x); x = 'D';
default:
continue;
}
You start with A. Since x != 'D' you enter the while loop.
Now the flow is the following:
enter case 'A'
print A and assign x = 'D'
fall-through to case 'B'
print D (since x == 'D') and assign x = 'C'
fall-through to case 'C'
print C (since x == 'C') and assign x = 'D'
fall-through to default (which will normally be reached, when you can't find a matching case)
continue (which means return to the start of the while loop)
Since x == 'D' the condition evaluates to false and won't enter the loop.
==> Result: ADC is printed.
Yes, you forgot the breaks between the steps. So all steps after the matching case will be executed. Try it with:
switch (x) {
case 'A':
System.out.print(x);
x = 'D';
break;
case 'B':
System.out.print(x);
x = 'C';
break;
case 'C':
System.out.print(x);
x = 'D';
break;
}
Switch statements have what is called "fall through".
You need a break at the end of every case, otherwise all of them will run, as is happening here.
char x = 'A'; //starts off as A
while(x != 'D') {
switch(x) {
case 'A':
System.out.print(x); x = 'D'; //here is gets printed and changed to D
case 'B': //you fall through here because there's no break
System.out.print(x); x = 'C'; //print again then change to C
case 'C': //fall through again
System.out.print(x); x = 'D'; //print again then change to D
default:
continue;
You only enter the case if it matches (so if it starts as C it will only print once) but once a match is found you can fall through to the other cases as well.
If you add breaks, then you won't fall through anymore.
char x = 'A';
while(x != 'D') {
switch(x) {
case 'A': //match
System.out.print(x); x = 'D'; //print then modify
break; //break
case 'B':
System.out.print(x); x = 'C';
break;
case 'C':
System.out.print(x); x = 'D';
break;
default:
continue;
look at this switch:
int a = 0;
switch(a) {
case 0:
System.out.println("0");
case 1:
System.out.println("1");
}
The lines of code which are executed are:
int a = 0;
System.out.println("0");
System.out.println("1");
In order to only execute the statement you want to execute you have to use break at the end of every case:
int a = 0;
switch(a) {
case 0:
System.out.println("0");
break;
case 1:
System.out.println("1");
break;
}
When first time switch executes, case 'A' selected, prints A and set x to 'D',
There no break between cases, so next line executes - print D (as x set to 'D' before) and set x to 'C'. And so on.
I have the following code to evaluate my expression tree. But the problem is it gives me wrong answer. I have tested around and found that when I code
double left = (double) Character.digit((char) evaluateTree(t.left),
10);
left value gets equal to -1 which I believe the double value of '+'. When I call root.left (which is '+') and try to get its double value with the Character.digit(char) it gives me -1. Since my tree is like :
//My infix : (2+5)*7 MyPostfix : 25+7*
*
/ \
+ 7
/ \
2 5
Evaluate method :
public double evaluateTree(TreeNode t) {
if(root == null)
return 0;
if (Character.isDigit(t.ch))
return (double)t.ch;
else {
char c = t.ch;
double left = (double) Character.digit((char) evaluateTree(t.left),
10);
double right = (double) Character.digit(
(char) evaluateTree(t.right), 10);
//checks what to do for operators for example for '+' return left+right
return evaluate(c, left, right);
}
}
Current result = -7.0
How do I fix this problem?
public double evaluate(char c, double left, double right) {
double result = 0;
switch (c) {
case '+':
result = left + right;
break;
case '-':
result = left - right;
break;
case '*':
result = left * right;
break;
case '/':
result = left / right;
break;
case '%':
result = left % right;
break;
}
return result;
}
Don't call Character.digit() on the result of evaluateTree(). evaluteTree() and evaluate() return a double, not a character that needs to be turned into a double. It's
if (Character.isDigit(t.ch))
return (double)t.ch;
where you need the Character.digit() call.
The program in java is to evaluate the post-fix arithmetic expression.
I am not getting any error in my program but I am getting the wrong output.
I am trying to evaluate the expression (1*(((2+3)*(4-5))+6)) where its result is 1.
But I am getting the output as 11.
Its post-fix expression is 1 2 3 + 4 5 - * 6 + *
Looking forward for your help.
Thank you!!
public static void evaluatePostfix(String sol)
{
ArrayStack<Double> nlist = new ArrayStack<Double> ();
double op1, op2, result;
char ch;
for (int i = 0; i < sol.length(); i++)
{
if ('0' <= sol.charAt(i) && sol.charAt(i) <= '9')
nlist.push((double)(sol.charAt(i) - '0'));
else
if (sol.charAt(i)=='+'||sol.charAt(i)=='-'||sol.charAt(i)=='*'||sol.charAt(i)=='/')
{
op1 = nlist.pop();
op2 = nlist.pop();
ch = sol.charAt(i);
switch(ch){
case '+':
nlist.push(op1 + op2);
break;
case '-':
nlist.push(op1 - op2);
break;
case '*':
nlist.push(op1 * op2);
break;
case '/':
nlist.push(op1 / op2);
break;
default:nlist.push(0.000);
}
}
}
result = nlist.pop();
System.out.println(result);
}
When you pop from the stack, op2 is the element at the top and op1 is at top-1. Change it to:
op2 = nlist.pop();
op1 = nlist.pop();
To be more clear if your postfix expression is 56 - (so 5-6 in infix) your stack is
| 6 |
| 5 |
and when you get the - you are doing nlist.push(op1 - op2); which pushes 6-5 into the stack while you should push 5-6.
I have two hex strings:
string x = "928fe46f228555621c7f42f3664530f9";
string y = "56cd8c4852cf24b1182300df2448743a";
I'm trying to convert them to binary to find how many bits matches between the two hex strings.
I used this function to convert HEX to Binary:
string GetBinaryStringFromHexString (string sHex)
{
string sReturn = "";
for (int i = 0; i < sHex.length (); ++i)
{
switch (sHex [i])
{
case '0': sReturn.append ("0000"); break;
case '1': sReturn.append ("0001"); break;
case '2': sReturn.append ("0010"); break;
case '3': sReturn.append ("0011"); break;
case '4': sReturn.append ("0100"); break;
case '5': sReturn.append ("0101"); break;
case '6': sReturn.append ("0110"); break;
case '7': sReturn.append ("0111"); break;
case '8': sReturn.append ("1000"); break;
case '9': sReturn.append ("1001"); break;
case 'a': sReturn.append ("1010"); break;
case 'b': sReturn.append ("1011"); break;
case 'c': sReturn.append ("1100"); break;
case 'd': sReturn.append ("1101"); break;
case 'e': sReturn.append ("1110"); break;
case 'f': sReturn.append ("1111"); break;
}
}
return sReturn;
}
So String x in binary is-->
10010010100011111110010001101111001000101000010101010101011000100001110001111111010000101111001101100110010001010011000011111001
and String y in binary is --> 01010110110011011000110001001000010100101100111100100100101100010001100000100011000000001101111100100100010010000111010000111010
But now I'm stuck, how can I xor the two strings to find the number of matching bits ? and how can I count them?
It doesn't matter whether I use Java or C++, can anyone help please
Thank you,
In Java it's pretty easy.
public static int numberOfMatchingOnes(String a, String b) {
BigInteger aNumber = new BigInteger(a, 16);
BigInteger bNumber = new BigInteger(b, 16);
return aNumber.xor(bNumber).bitCount();
}
In C++ you might use a bitset. What you're looking for is called Hamming weight.
If you really want to do it without BigInteger:
Take 4 chars of both strings, convert them into an int, xor them and count the one-bits. Repeat until the strings end.
public static int numberOfMatchingOnes(String a, String b) {
if (a.length() != b.length() || a.length() % 4 != 0) {
throw new IllegalArgumentException("invalid strings");
}
int totalCount = 0;
for (int i = (a.length()-1)/4; i >= 0; i--) {
int aValue = Integer.valueOf(a.substring(i * 4, i * 4 + 4), 16);
int bValue = Integer.valueOf(b.substring(i * 4, i * 4 + 4), 16);
totalCount += Integer.bitCount(aValue ^ bValue);
}
return totalCount;
}
You can look at the Java Sourcecode to see how bitCount() works.
You have two strings. Why not run through them character by character and see if they match or not? Initialize a counter to zero and start incrementing them for each match and display at the end of the loop. Much simpler.
Here is a one-liner solution though (with the power of all the libraries in the world):
System.out.println(StringUtils.countMatches(new BigInteger("928fe46f228555621c7f42f3664530f9",16).xor(new BigInteger("56cd8c4852cf24b1182300df2448743a",16)).toString(2),"1"));
It depends your purpose if you want to find where they matched together you can use AND
in C :
#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 & b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
}
the above code from right to left compare numbers in binary and wherever a two bit were 1 then return 1 else return 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if you want to find where are the same or not use XOR
in C :
#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 ^ b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
}