Alright, so I'm trying to make an expression-as-a-string solver, so that the user can input a string, such as 2+4*5/10, and it will print out the answer, 4. I have some code written, but it doesn't apply the order of operations; it simply solves the equation in order of the operators - e.g. 2+4*5/10 would produce 3, which is incorrect. How do I make it so that multiplication and division are performed first, then addition and subtraction?
Here's the code I have right now:
class Expressions
{
String E;
void SetE(String e)
{
E = e;
}
int EvalE()
{
int res = 0;
int temp = 0;
char op = '+';
for(int i=0;i<E.length();i++)
{
if(E.charAt(i)=='*'||E.charAt(i)=='/'||E.charAt(i)=='+'||E.charAt(i)=='-')
{
if(op=='*')res*=temp;
else if(op=='/')res/=temp;
else if(op=='+')res+=temp;
else res-=temp;
temp=0;
op=E.charAt(i);
}
else
{
temp = temp*10+E.charAt(i)-'0';
}
}
if(op=='*')res*=temp;
else if(op=='/')res/=temp;
else if(op=='+')res+=temp;
else res-=temp;
return res;
}
}
Split the expression into two simpler expressions, then use recursion.
You have to do the following steps in precisely this order, or you will mess up the order of operations.
Look for the rightmost + sign. If there is such a +, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then add them and return the result.
If there's no + sign, then look for the rightmost - sign that's preceded by a number (that is, it's subtraction, not negation). If there is such a -, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then subtract them and return the result.
If there's no + or - sign, then look for the rightmost * sign. If there is such a *, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then multiply them and return the result.
If there's no +, - or * sign, then look for the rightmost * sign. If there is such a *, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then divide them and return the result. If you're using integers, you'll have to think about whether you want integer division or floating point. You might also want to do some kind of check around dividing by zero.
If there's no +, -, * or /, then all you've got is numbers and whitespace. Maybe a negative sign. Strip out the whitespace, parse it and return it.
Example: "6 - 5 - 4 + 3 * -2"
First, split at the +, and use recursion to evaluate "6 - 5 - 4 " and
" 3 * -2".
For "6 - 5 - 4 ", split at the second - , and use
recursion to evaluate "6 - 5 " and " 4 ".
For "6 - 5 ", split at the -, and use recursion to evaluate "6 " and " 5 ".
For " 3 * -2", split at the *, because the - is not preceded by a number. Use recursion to evaluate " 3 " and " -2 ".
For each of "6 ", " 5 ", " 4 ", " 3 " and " -2 ", there are no operators, so we just strip out the white space and parse.
The result of our calculation will be "((6-5)-4)+(3*-2)", so the order of operations worked out correctly.
Use two for loops.
In your first loop, search for * and / operators. Evaluate that part and replace that part of the string with the result of the evaluation.
In your second loop, do all the + and - as you're already doing.
So for the example you use, 2+4*5/10, your first loop would look for * or /. Upon finding the *, it evaluates 4*5. That's 20, so the string is modified into 2+20/10. Check again, and it finds the /, and modifies the string into 2+2.
Now you go through your second loop, and get 4.
You need to do two steps instead of one. In first step you parse equation into the reverse polish notation, then in second step you run through that and calculate results. Nice bonus is you get brackets support for (almost) free :-)
Related
problem link: https://leetcode.com/problems/string-to-integer-atoi/
i have implemented my solution but it fails for testcase like "-+42"since 2 consecutive signs appear in string. what changes do i need to do in my code, and where am i wrong? help would be appreciated
my code:
class Solution {
public int myAtoi(String s) {
s=s.trim();
char sign='+';
if (s.length()==0) return 0;
String digit="";
for(int i=0;i<s.length();i++)
{
//checking for sign
if(s.charAt(i)=='-'||s.charAt(i)=='+')
sign=s.charAt(i);
//checking for all non digit characters
else if((s.charAt(i)>='a'&& s.charAt(i)<='z')||(s.charAt(i)>='A' && s.charAt(i)<='Z')||(s.charAt(i)==' ')||(s.charAt(i)=='.')||(s.charAt(i)=='-')||(s.charAt(i)=='+'))
break;
else{
digit=digit+s.charAt(i);
}
}
if(digit=="") return 0;
//System.out.print(sign);
try{
int n=(Integer.parseInt(digit));
//int a=Integer.parseInt(digit);
System.out.print(sign);
if(sign=='-')
return (-n);
return n;
}
//check for out of range for integer
catch(NumberFormatException e)
{
if(sign=='-')
{
//
int n=Integer.MIN_VALUE;
return n;}
else
{
int n=Integer.MAX_VALUE;
return n;
}
}
}
}
Er, just.. do what the exercise says? Not sure what you want to hear from SO here. I guess: "Can you regurgitate the question to me". Can do!
Your algorithm isn't doing anything like what the exercise spells out you need to do. You are triggering on a sign character appearing anywhere, and your code scans for letters, all things which the exercise doesn't mention. At all. The exercise mentions the concept of a 'not a digit' and the first character (after getting rid of spaces, which you already did with a trim() invocation).
So, do what the exercise says:
Instead of if (s.charAt(i) == '-' your code needs to involve s.charAt(0) - there are only 3 options:
The trimmed string starts with a +. Set the sign to +, and start looking at digits from position 1.
The trimmed string starts with a -. Set the sign to -, and start looking at digits from position 1.
Neither. Set the sign to + and start looking at digits from position 0.
Your s.charAt(i) >= 'a' is also wrong. You're not looking for a letter. You're looking for anything that isn't a digit. + isn't a letter. Nevertheless, in input -5+10, you're supposed to return -5. In -+10 you're supposed to return 0. (Because that's like -hello - the negative value of no digits, which is minus zero, which is just zero).
I think the intent of the exercise is not to use Integer.parseInt whatsoever.
Try this algorithm:
if your character is >= '0' and <= '9', you can subtract '0' to get the actual digit in integer form: char c = '5'; int y = c - '0'; System.out.println(y); would print 5.
multiply your existing input by 10, then add the digit you have. In other words, for text input "29", first you read a 2, you multiply the number you're working on (0, at first) to 10 (still 0), then you add 2, giving you 2. Then you get another digit, so you multiply what you ahve so far by 10 (giving you 20), and add the digit value, getting you the integer 29. No need for parseInt.
You now you need to clamp when your working total flips signs on you. So, if all of a sudden your input is negative (as you won't yourself make it negative until the very end), you know you have to clamp and return Integer.MIN_VALUE or Integer.MAX_VALUE, depending on the sign value.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am working on a project. I found this code regarding permutations on the Interwebz. I would like to use it as a basis for writing my own code. However, I don't really understand what is going on in the code. Could anybody lend me a hand and explain what the code is doing exactly?
public void permutations(String prefix, String s) {
int n = s.length();
if (n == 0)
System.out.println(prefix);
else {
for(int i = 0; i < n; i++){
permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));
}
}
}
The method permutations is taking in a String prefix and a String s as its parameters.
The int type n is being set to the length of the String s. (length of a String being how many characters it contains).
Now we move on to the if-else statements. The if statement is saying, if the length of s is 0, that is, s is a blank String and does not contain any information, then we are simply printing the String prefix instead to the console. The method will then skip over the else part and execute the code after the permutations method.
If the if statement's conditions are not met, we are going to run the else statement is saying, for each character in the String s, we are going to append (add) that character at the end of prefix, so for example, if prefix was originally "hello" and the character was 'U', we would get prefix to be "helloU". After we are finished appending all of the characters in s, we are going to be using the result as the new prefix String.
For the other parameter, the String s, we are going to be taking part of the String, from character 0 (inclusive) to character at position i (exclusive). Please note that the String indexes start at 0 and go up to (The length of the String - 1). We are also taking the part of the String from the character at position i + 1 (inclusive) to the last character in the String s. We are going to use this result as the new s String.
Then we would be calling the method again, and then the method would execute again with the newly defined Strings if the else condition is met. This would continue in a loop until the else condition is not met, at which point the method would stop running and we would move on to the next section of code (if it is present).
p(String prefix, String s) takes 1 character out of s and adds it to prefix and recursively continues until s is empty.
The s.charAt(i), s.substring(0, i) + s.substring(i+1, n) part extracts a character from s.
Assume s = "Magic!" and i = 3 then charAt(i) = 'i', s.substring(0, i) = "Mag" and s.substring(i+1, n) = c!". That spilts Magic! into i and Magc!. Next time in the loop with i = 4 it will result in c + Magi!. Since it does that for every character in s every character will be in the front in one of the recursive steps.
The call hierarchy would look like this
/ p("ab", "c") - "abc"
/- p("a", "bc") x
/ \ p("ac", "b") - "acb"
/
/ / p("ba", "c") - "bac"
p("", "abc") x ---- p("b", "ac") x
\ \ p("bc", "a") - "bca"
\
\ / p("ca", "b") - "cab"
\- p("c", "ab") x
\ p("cb", "a") - "cba"
^-- 1st for loop ^- 2nd for ^- 3rd one prints
permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));
Actually, this permutation algorithm is using the idea of
Switching current character with ith character.
Suppose we have a string abc. So the permutation of it is:
abc, acb, bac, bca, cab, cba
We can find that the acb is just switching b and c in abc with prefix a. And the bca is just switching c and a in bac with prefix b.
Then we just use the same idea to recursively solve permutation problem.
This is some really confusing code, for two reasons:
The prefix argument: you should call this function with an empty string in the first argument, for example permutations("", "ab") to print all (both) permutations of "ab".
The recursive call with s.substring(0, i) + s.substring(i+1, n) in the second argument: note that java's String.substring(x,y) will not include the y-th character. So this amounts to passing s with the y-th character deleted.
Now think what happens as you step through the for loop: the first argument becomes "" concatenated with "a", i.e. "a", and the second argument becomes s with the first character deleted, i.e. "b". In the next recursive subcall, prefix becomes "ab" and the second argument becomes the empty string "". So the base-case n == 0 gets hit and we print the result "ab".
Now we go to the next iteration of the for loop, i == 1. Now we pass "b" in the first argument of our recursive subcall, and "a" in the second argument. In the next recursive subcall prefix becomes "ba" and s.length is 0, so base case again: print "ba".
It's clever, but inscrutable.
I'm doing some error checking for my BigInteger Calculator class. If an input has a space in between numbers and no valid operator (+,-,*,/,%,^) in between those numbers like the one below it is supposed to return "Error". Is there any way to check for this case using string methods?
Should return error because there is space in between numbers and no operator in between them:
2 + 1 1 1 1 1 + 2 //in this case the 1's do not have operators in between
2 2 2 //has spaces in between
valid:
2 + 2
22 + 2 + 1
2 + 11111 + 2
One option would be to split the string using String[] temp = [stringName].split(" "); and check to see that every other index is a valid operator.
Perhaps you can use regex to find space in between numbers.
String input = "1+2 2 2";
boolean found = Pattern.compile("[0-9]+\\s+[0-9]+").matcher(input).find();
You don't need to find the space between numbers specifically. In fact you should be ignoring spaces completely other than as delimiting the tokens.
You just need to scan and parse according to a grammar that doesn't have a syntax for two consecutive numbers. Or operators. At any given point you should know what's expected and what isn't.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am working on a project. I found this code regarding permutations on the Interwebz. I would like to use it as a basis for writing my own code. However, I don't really understand what is going on in the code. Could anybody lend me a hand and explain what the code is doing exactly?
public void permutations(String prefix, String s) {
int n = s.length();
if (n == 0)
System.out.println(prefix);
else {
for(int i = 0; i < n; i++){
permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));
}
}
}
The method permutations is taking in a String prefix and a String s as its parameters.
The int type n is being set to the length of the String s. (length of a String being how many characters it contains).
Now we move on to the if-else statements. The if statement is saying, if the length of s is 0, that is, s is a blank String and does not contain any information, then we are simply printing the String prefix instead to the console. The method will then skip over the else part and execute the code after the permutations method.
If the if statement's conditions are not met, we are going to run the else statement is saying, for each character in the String s, we are going to append (add) that character at the end of prefix, so for example, if prefix was originally "hello" and the character was 'U', we would get prefix to be "helloU". After we are finished appending all of the characters in s, we are going to be using the result as the new prefix String.
For the other parameter, the String s, we are going to be taking part of the String, from character 0 (inclusive) to character at position i (exclusive). Please note that the String indexes start at 0 and go up to (The length of the String - 1). We are also taking the part of the String from the character at position i + 1 (inclusive) to the last character in the String s. We are going to use this result as the new s String.
Then we would be calling the method again, and then the method would execute again with the newly defined Strings if the else condition is met. This would continue in a loop until the else condition is not met, at which point the method would stop running and we would move on to the next section of code (if it is present).
p(String prefix, String s) takes 1 character out of s and adds it to prefix and recursively continues until s is empty.
The s.charAt(i), s.substring(0, i) + s.substring(i+1, n) part extracts a character from s.
Assume s = "Magic!" and i = 3 then charAt(i) = 'i', s.substring(0, i) = "Mag" and s.substring(i+1, n) = c!". That spilts Magic! into i and Magc!. Next time in the loop with i = 4 it will result in c + Magi!. Since it does that for every character in s every character will be in the front in one of the recursive steps.
The call hierarchy would look like this
/ p("ab", "c") - "abc"
/- p("a", "bc") x
/ \ p("ac", "b") - "acb"
/
/ / p("ba", "c") - "bac"
p("", "abc") x ---- p("b", "ac") x
\ \ p("bc", "a") - "bca"
\
\ / p("ca", "b") - "cab"
\- p("c", "ab") x
\ p("cb", "a") - "cba"
^-- 1st for loop ^- 2nd for ^- 3rd one prints
permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));
Actually, this permutation algorithm is using the idea of
Switching current character with ith character.
Suppose we have a string abc. So the permutation of it is:
abc, acb, bac, bca, cab, cba
We can find that the acb is just switching b and c in abc with prefix a. And the bca is just switching c and a in bac with prefix b.
Then we just use the same idea to recursively solve permutation problem.
This is some really confusing code, for two reasons:
The prefix argument: you should call this function with an empty string in the first argument, for example permutations("", "ab") to print all (both) permutations of "ab".
The recursive call with s.substring(0, i) + s.substring(i+1, n) in the second argument: note that java's String.substring(x,y) will not include the y-th character. So this amounts to passing s with the y-th character deleted.
Now think what happens as you step through the for loop: the first argument becomes "" concatenated with "a", i.e. "a", and the second argument becomes s with the first character deleted, i.e. "b". In the next recursive subcall, prefix becomes "ab" and the second argument becomes the empty string "". So the base-case n == 0 gets hit and we print the result "ab".
Now we go to the next iteration of the for loop, i == 1. Now we pass "b" in the first argument of our recursive subcall, and "a" in the second argument. In the next recursive subcall prefix becomes "ba" and s.length is 0, so base case again: print "ba".
It's clever, but inscrutable.
public static void main(String[] args) {
int x = 1 + + + + + + + + + 2;
System.out.println(x);
}
I can compile above method. Is there any explanation about the allowed multiple "+" operator?
It's addition, then the unary plus operator repeated. It's equivalent to the following:
int x = 1 + (+ (+ (+ (+ (+ (+ (+ (+ 2))))))));
The reason is that + can act as a unary operator, similar to how - can be the negation operator. You are just chaining a bunch of unary operators together (with one final binary addition).
it evaluates to 1 + (+ ... (+(+(+2))) ... ) = 1 + 2 = 3
I think they treated all those plus as the same one +. Because the output is 3, so there is no magic here at all
you do not get any exceptions, it works fine. You will get output 3.
Its because though syntactically it may seem wrong use of '+' but there is this unary operation is repeating itself.