JAVA Reverse Polish Notation using Stacks - java

I wrote the following code based on the Wikipedia algorithm for RPN using Stacks:
public static void reversePolish(String[] x){
Stack temp = new Stack();
Integer one;
Integer two;
Integer result;
for(String x1:x){
switch(x1){
case "+":
one = (Integer) temp.pop();
two = (Integer) temp.pop();
result = one+two;
System.out.println(one + "+"+two);
temp.push(result);
break;
case "-":
one = (Integer) temp.pop();
two = (Integer) temp.pop();
result = one+two;
temp.push(result);
break;
default :
temp.push(Integer.parseInt(x1));
}
}
result = (Integer) temp.pop();
System.out.println(result);
}
However it gives me an error:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at TestingItOut.reversePolish(TestingItOut.java:57)
at TestingItOut.main(TestingItOut.java:31)
C:\Users\Sanchit\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
I have absolutely no idea what raises the error. HELP NEEDED

I don't think throwing an EmptyStackException is the problem with your program - it runs perfectly well on my computer.
The reason that an EmptyStackException is thrown is probably the data you pass to reversePolish().
As an example, a valid input should be:
"1", "2", "+", "3", "-", "6", "+"
Which means 1+2-3+6. That is, if you wish to calculate a result with a binary operator and 2 operands, write the operands first and put the operator after them.
For more details, see Reverse Polish Notation.
So why was an EmptyStackException thrown?
Your algorithm is simple: on an operand, push it into a stack, on an operator, pop the operands, calculate the result, and push it back. The problem is, if the program finds an operator and the stack does not contain sufficient operands, it still tries to pop the 2 required operands, and, EmptyStackException.
To polish the algorithm, you can first check the size of stack before popping, and print a human-readable message saying "There's not enough operands!" instead of throwing an EmptyStackException. The code could be like this: (partial)
case "+":
if (temp.size() < 2) {
System.out.println("There's not enough operands!");
return;
}
one = (Integer) temp.pop();
two = (Integer) temp.pop();
result = one + two;
System.out.println(one + " + " + two);
temp.push(result);
break;
Something more.
In case you haven't noticed, you've written result = one + two; under case "-":, which I take as a simple typo error. It should be result = one - two.
And if you run the program in an environment equal to or higher than Java 1.5, Stack should contain an generic type. In your case, it should be Stack<Integer> temp = new Stack<Integer>();. (If you're in Java 7 or newer, you can write Stack<Integer> temp = new Stack<>(); for the sake of simplicity) And then you don't have to write one = (Integer) temp.pop();. one = temp.pop() is okay.
One more thing:
You simply write result = (Integer) temp.pop(); at the end, which is still not the perfect thing.
Imaging the input being "1", "2", "+", "3", "-", "6", "+", "7".
Translated, it's 1 + 2 - 3 + 6 7. If you write this down and give it to your teacher, you will get a zero mark, because there's no operator connecting 6 and 7 - that is, 7 is redundant.
However, if you give this to your program, it will output 7 instead of croaking some warnings. This is not the desired behavior.
So, the right thing to do is, write:
if (temp.size() == 1) {
result = (Integer) temp.pop();
System.out.println(result);
} else System.out.println("Redundant operands!");

Put the break; command and all of it seemed to work. Not gonna fiddle around with it too much now!

Related

Get random operators and integers

im doing an assignment which requires me to create 3 classes.
1 with getting 2 random integers,
1 with getting random operators such as + - * / which should be done so in char method
the last one to check if the simple mathematics answer is correct using booleans via user Scanner input.
i need a little help here as im not sure if i've done the random operators method correctly and am really lost at how i should tabulate both random int and operators together in one class.
here's the code i've done so far:
public static char getOperator (int x, int y)
{
char operator;
int answer;
switch (rand.nextInt(4))
{
case 0: operator = '+';
answer = x + y;
break;
case 1: operator = '-';
answer = x - y;;
break;
case 2: operator = '*';
answer = x * y;;
break;
case 3: operator = '/';
answer = x / y;;
break;
default: operator = '?';
}
return operator;
}
I believe you mean you need to create 3 methods (and not classes).
One that creates a random integer (it's a bad design to create a
method that returns two integers instead of just calling two times
one that returns one int).
One that returns a random operator
One that checks if an operation consisting of "random-number
random-operator random-number" is equal to user input
Anyways, there's a lot to unpack here, so:
Your first method getTwoIntegers is incorrect, you're asking for two integers in input but you never actually use them, then you return one random number.
The method getOperator needs to be redesigned to have no input and return one char (equal to + - x /).
Your final method will call the your first method twice, then the second method once, it will then print the operation for the user to see, and check if the response is correct.
Hopefully this can help you conceptualize better the way you should build your code.
I didn't post the source code since I believe it's much better for you if you try to do it by yourself (this being an assignment and all)
Good luck and have fun :)

Finding a string inside a string twice as big effectively

I'm looking to see if the difference between every adjacent number in an array is the same as another array, or a rotation of it, for example
A = {1,2,4}, so the differences are {1,1,2}
B = {4,6,7}, the differences are {1,2,1}
If all elements in {1,2,1} were moved clockwise one-element, the result is {1,1,2}, which is correct.
so far I convert the differences to strings, and then see if the differences of the second array is found in the first concatenated with itself
valid if "1 2 1" is in "1 1 2 1 1 2"
my code so far looks like this
count is the length of the array, both have the same length
int c = count - 1;
StringBuilder b1 = new StringBuilder();
StringBuilder b2 = new StringBuilder();
for (int i = 0; i < c; i++) {
b1.append(array1[i + 1] - array1[i]);
b1.append(" ");
b2.append(array2[i + 1] - array2[i]);
b2.append(" ");
}
b1.append((array1[0] - array1[c]) + d);
b1.append(" ");
b2.append((array2[0] - array2[c]) + d);
String a2 = b2.toString();
String a3 = b1.toString() + b1.toString();
System.out.println(a3.contains(a2) ? "valid" : "not valid"); //bottleneck here
My problem is when I use big arrays (up to about 250,000 elements) I get a massive bottleneck at the last line with the .contains(). I'm wondering if there is either a faster way of check if its inside the method than what I'm using, or if I can check while building up the string, or if there is a completely different way of doing this?
You need a more efficient algorithm then the one that is used in contains method(it actually depends on a concrete implementation, but it looks like it is not efficient in the version of Java you are using).
You can use Knuth-Morris-Pratt algorithm: http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm. It has linear time and space complexity in the worst case so it works fast even for very big arrays. Note that there is no need to convert an array to a string, because this algorithm works for arrays, too.

Convert String to operator(+*/-) in java

I am using Stack class to calculate simple arithmetic expressions involving integers,
such as 1+2*3.your program would execute operations in the order given,without regarding to the precedence of operators.
*Thus, the expression 1+2*3 should be calculated (1+2)*3=9,not 1+(2*3)=7.
If i get the input as 1+2*3,i know how to convert the string 1,2,3 to Integer.but i don't know how to covert +,* from string type to operator.
My code logic is:
For eg: Given string 2 + (3 * 5), So 3 * 5 will be operated first then +2 will be performed in result of 3 * 5.
probably the best way to do it will be equals, but it's best to ignore whitespaces:
i'm not quite sure how you split your string, but for example, if you have a char op and two integer a and b:
String str = op.replace(" ", "");
if(str.equals("*")){
retVal = a*b;
} else if(str.equals("+")){
retVal = a+b;
}//etc
Do what Ogen suggested and manually check the operator. A quick shortcut to doing the if, else if .... structure is switch, that is
switch(operand) {
case "*":
break;
case "+":
break;
.....
default:
}
You will have to manually check and assign the operator. E.g.
if (s.equals("+")) {
// addition
}
Quick solution: Use below code for executing correct javascript Arithmetic expression in java.
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine se = manager.getEngineByName("JavaScript");
try {
Object result = se.eval(val);
System.out.println(result.toString());
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Ok, assuming your assignment needs you to use the Stack class and you already have the logic to pick numbers ( including the negative numbers -- that would an operator followed by another operator in all but one cases) and operators and parens, what you could do is as follows.
If you encounter a number, pop the last two elements from your stack. The first item you pop will be an operator and the next will be a number. Evaluate the expression and push it into Stack and continue.
You can ignore the parenthesis. You will also have to handle the case of reading a number or parenthesis the first time.

Java String += Shorthand explanation needed

While I was creating a program to compress a string I ran into this strange problem, I will paste the code snippets with their outputs, I would like someone to clearly explain why this is happening.
The first code snippet: here if same letter appears consecutively, then the successive occurrences of the letter is replaced by the total count of same letters. Ex: aaabbb should be written as a3b3.
public static String compress(String str){
String compressed = "";
char prev = str.charAt(0);
int count = 1;
for (int i = 1; i < str.length(); i++) {
char curr = str.charAt(i);
if (curr == prev) { // in case curr is equal to prev
count++;
} else { // in case curr is not equal to prev
//compressed=compressed+prev+count;
compressed+=prev+count; // Shorthand used here
count=1;
prev=curr;
}
}
compressed=compressed+prev+count; // Shorthand not used
System.out.println(compressed);
return compressed;
}
the output for this above code when inputted with aabbccaabbccaabbccaabb is 99100101991001019910010199b2, observe the last two elements of the output, this is because outside the loop, shorthand is not used. If I write the expression as compressed = compressed +prev+count inside the loop, I'll get the intended output.
I thought this output is because the operation is messing with the address of the String. But the next code confused me again.
String prev= "abc";
String curr = "def";
String result="";
result+=prev+curr;
System.out.println(result);
I think this is because the right hand operation is performing an ASCII addition, I cannot come to a conclusion, can anyone clarify.
I am sleep deprived and hence I am not able to come to a conclusion, hence asking someone to clarify my trivial doubt.
It has nothing to do with the reference. When you did prev+count ascii value of the character in prev is added with the integer count. In this case :
ascii of "a" is 97, and it occurred twice... so 97 +2 = 99 ..
ascii of "b" is 98, and it occurred twice... so 98 +2 = 100 ..
ascii of "c" is 99, and it occurred twice... so 99 +2 = 101 ..
that's why the output is 99100101991001019910010199100
try this : compressed+=(""+prev)+count; // Shorthand used here
In this case, or in compressed+=""+prev+count case, since the operation happens from left to right, the + operator is applied on a string ("") and char(prev) and behaves like append and also returns a string. The resulting string is then appened with another int (prev)
A better way is using a StringBuilder
Take a look at this subject and at JLS 15.18.1 section :
You see this behavior as a result of the combination of operator
precedence and string conversion.
JLS 15.18.1 states:
If only one operand expression is of type String, then string conversion (ยง5.1.11) is performed on the other operand to produce a
string at run time.
Therefore the right hand operands in your first expression are
implicitly converted to string: string = string + ((char)65) + 5;
For the second expression however string += ((char)65) + 5; the +=
compound assignment operator has to be considered along with +.
Since += is weaker than +, the + operator is evaluated first.
There we have a char and an int which results in a binary numeric
promotion to int. Only then += is evaluated, but at this time
the result of the expression involving the + operator has already been evaluated.
Whenever you add a char to an int in java first it converts the character into its equivalent ASCII value and then adds it to the integer
eg suppose the following scenario ,
char c = 'a'; // ASCII value of 'a' is 97
int i = c + 5 ; // result will be 97 + 5 = 102
I think this answers your first half question
Now the Second part ,
Whenever you use the shorthand operator in Java the expression at right hand side is evaluated first.
Hence , for expresion
result += prev + curr it is evaluated as
result = result + (prev + curr);
Therefore ,
result+=prev+curr; // Here first it appends "abc" with "def" and then the resultant "abcdef" is appended to as result .
you can convert your charater value "prev" to string and than append count to it.
compressed += Character.toString(prev) + count;

Evaluating postfix expression using recursion

I need an algorithm for evaluating postfix expression using recursion. In this postfix expression an operand can be of more than one digit. A space is used to distinguish between two operands. So an expression '45 68 +' is valid.
I thought of evaluating it in reverse direction but I think that should not be correct.
Can someone help me with just the algorithm.
Thanks in advance.
Doesn't strike me as a recursive-friendly problem. But I'm sure it could be done that way.
Two approaches occur to me:
Option #1: Make functional recursion calls and returns match the stack push and pop operations described on the Wiki.
Down side to this approach is that you'll quickly find that the returned data from the function can be fairly complex. It'll probably be an operator. Maybe with an optional operand (IE: number). You'll be returning structures/objects that maybe should have operations (methods) on them.
Option #2: Each recursive call processes the next character of the input stream.
I think this approach would pass in as parameters the stack and maybe an "accumulator" for the current number -- to accumulate digits into a number before pushing it on the stack. There would be one massive tail recursion numeric result returned.
This approach is really just rewriting a loop as recursion.
Either way, figuring it out yourself should be challenging and educational!
Following is a sort of pseudo code which will work for postfix expressions with +/- . I think you can further extend the idea. If you still face difficulty then mail me to 2shanks.p#gmail.com as I am not regular on this site.
void recursivePostfix(char* expr)
{
if(!expr) return;
bool flag=true;
static double result=0;
double v1=result, v2=0, dec=0;
char oper='0';
int i=0, state=1;
do
{
if('0' != oper)
{
switch(oper)
{
case '+': result=v1+v2; break;
case '-': result=v1-v2; break;
case '*': result=v1*v2; break;
case '/': result=v1/v2; break;
}
oper = '0';
v1 = result;
v2 = 0;
recursivePostfix(expr+i);
}
if(SPACE_CHAR == *(expr+i) && state++)
continue;
switch(state)
{
case 1:
v1 = v1*10 + (expr[i]-'0'); break;
case 2:
v2 = v2*10 + (expr[i]-'0'); break;
case 3:
oper = *(expr+i);
}
}while(0 != *(expr+i++));
cout << result;
}
I just code this for an interview, so here is my solution using Python:
def recursive_postfix(s):
s = s.split(' ')
if len(s) == 1:
return s[0]
res = None
for i in range(len(s)):
if s[i] in ['+', '-', '*', '/']:
res = eval(f'{s[i-2]}{s[i]}{s[i-1]}')
break
s = s[0:i-2] + [str(res)] + s[i+1:]
return recursive_postfix(' '.join(s))
assert recursive_postfix('2 2 + 1 *') == '4' # (2 + 2) * 1
assert recursive_postfix('3 4 2 + * 5 *') == '90' # 3 * (4 + 2) * 5
assert recursive_postfix('7 2 2 * -') == '3' # 7 - (2 * 2)

Categories