# 2 stacks, the second keeps mirroring the second??

• 10-11-2009, 02:28 AM
jigglywiggly
2 stacks, the second keeps mirroring the second??
Ok so this has to be something stupid, I mean everything in my project is done except for this.

Reverse polish notation calculator.
solve(), just solves the equation
printout() prints out the equation in normal form like (3+2)/5

So basically if I call one of these methods, it works. If I call both... not so much.

Here is my main
Code:

import java.util.*;
public class CalcStackDriver {

public static void main(String[] args) {
Stack j = new Stack();
j.push("/");
j.push("5");
j.push("*");
j.push("5");
j.push("/");
j.push(Integer.toString(3));
j.push("+");
j.push(Integer.toString(1));
j.push(Integer.toString(2));

CalcStack m = new CalcStack(j);
m.solve();
m.printout(); // If I comment m.solve then m.printout works

}

}

Here is where the main code lies:
Code:

import java.util.*;

public class CalcStack {

Stack theStack;
Stack forprinting;
double finalvalue = 0;
String temp10;
String temp11;
String temp12;
int count = 0;
int alternate=0;
int makingsure=0;

public CalcStack(Stack j) {
theStack = j;
forprinting=j;
}
public void solve() {

while (!(theStack.size() == 1)) {

double d = 0;

String temp = ((String) theStack.pop());
double j = Double.parseDouble(temp);

String temp2 = ((String) theStack.pop()).toString();
double m = Double.parseDouble(temp2);

String temp3 = ((String) theStack.pop()).toString();

if (temp3.equals("+")) {

d = j + m;
finalvalue = d;
String str = Double.toString(finalvalue);
theStack.push(str);

}

if (temp3.equals("*")) {
d = j * m;
finalvalue = d;
String str = Double.toString(finalvalue);
theStack.push(str);
}

if (temp3.equals("/")) {
d = j / m;
finalvalue = d;
String str = Double.toString(finalvalue);
theStack.push(str);
}

}

System.out.println(theStack.peek());

}

public void printout() {

temp10 = ((String) forprinting.pop());
temp11 = ((String) forprinting.pop());
temp12 = ((String) forprinting.pop());

while (!(forprinting.size() == 0)) {
count++;
}

for (int i = 0; i < count; i++) {
System.out.print("(");
}
System.out.print(temp10+temp12+temp11);
System.out.print(")");

System.out.print(")");
}
System.out.println("");

}
}

If I run it :
Code:

debug:
1.0
at java.util.Stack.peek(Stack.java:85)
at java.util.Stack.pop(Stack.java:67)
at CalcStack.printout(CalcStack.java:84)
at CalcStackDriver.main(CalcStackDriver.java:19)
Java Result: 1

This is meaning the second stack is empty, forprinting. I debugged the project and looked at forprinting, and its size keeps equaling to the size of the stack of "theStack". But why?
Why is it doing that? I mean it shouldn't, and it causes the project to fail.

And remember of these methods work if I call just one of them, not both... Any ideas?
• 10-11-2009, 03:21 AM
CodesAway
I'm not sure if you realize this, but when you run solve, you pop values, and push their result. As such, when you are done, the size of the stack is 1.

Then, when you call printout(), the stack is size 1, but you pop 3 three values at the beginning of the function. As such, an EmptyStackException occurs.

Also, maybe not intended, but your constructor only stores a reference to the stack, it does NOT clone the stack. Thus, using the below code, changing one stack affects the other, since they point to the same reference.

Code:

public CalcStack(Stack j)
{
// both stacks point to j, not a clone of j
// as such, changing j, or either stack, affects ALL
theStack = j;
forprinting = j;
}

Edit:
Also, if you run the same function twice, you will have the same problem, since you aren't working on a copy of the stack, but the actual stack. So, just some advice, verify that you can run the same method twice, as well as being able to run each one once.
• 10-11-2009, 06:33 AM
jigglywiggly
Oh I see that would make sense, how would I make theStack a copy of the the passed Stack "j"

Same for "forStack"

That would solve my issues. Oh and about when I run solve, yeah I know I have 1 left over.
• 10-11-2009, 06:44 AM
CodesAway
You don't want a "copy", you want a "clone", it's a method inherited from Vector, e.g. myStack.clone();

I put it as the first line in each of the two methods, works like a charm.

Code:

public void solve()
{
Stack theStack = (Stack) this.theStack.clone();

while (!(theStack.size() == 1)) {
...

Code:

public void printout()
{
Stack forPrinting = (Stack) this.forprinting.clone();

temp10 = ((String) forprinting.pop());
...

P.S. Just personal curiosity, but why aren't you using generics? Are you running it on a pre-Java 5 compiler? With generics, the code gets MUCH cleaner, since you can remove all those nasty (String) casts.

I don't usually comment on someone's syntax, but Eclipse has all these yellow lines (warnings), wondering why there is no type.
• 10-11-2009, 07:15 AM
jigglywiggly
I am using netbeans, my friend who has eclipse always tells me eclipse does casting for you or something, I never really listened in that much. (He always says eclipse is better)
• 10-11-2009, 07:17 AM
jigglywiggly
Oh and thanks so much for telling me about clone :D It works like a charm :D
I spent like 1 hour trying to figure out why they kept equaling each other :eek:
• 10-11-2009, 07:30 AM
CodesAway
I'm an eclipse user, so I'm biased, but it is true that Eclipse warns you when you write bad code. For example, it says that your code needs generics (and it is willing to automatically add them). Edit: It removes the casts to String too, didn't know that.

I personally like Eclipse, because where Netbeans yells at you for making a mistake, Eclipse allows you to hover on the mistake and offer you solutions - it's very user-friendly.

For example, I copied your code from Eclipse to NetBeans, to see how it looks there. I copied your code to a Test.java file that I was using for testing. In NetBeans, it yelled at me since the class name is "CalcStack", but the file is named "Test.java". In Eclipse, it would also yell at me, but it would have given me the option to rename my class to Test, or to rename the file to CalcStack.java. Also, in NetBeans, it says that you use raw type, but doesn't offer any solutions. In Eclipse, it gives me the option to "Infer Generic Type Arguments...". This updates ALL occurrences of raw type with the inferred type - does a good job for your Class.

It's small things like that that I love about Eclipse, and can't stand about Netbeans.

There are many other features too. My recommendation would be to download Eclipse, and try it out.
• 10-11-2009, 07:31 AM
CodesAway
Quote:

Originally Posted by jigglywiggly
Oh and thanks so much for telling me about clone :D It works like a charm :D
I spent like 1 hour trying to figure out why they kept equaling each other :eek: