I have a method that is passing an array in as reference and I use recursion to call this method over several times. I use the array as a “stack”. The code is for a calculator which translates postfix to infix and is just a simple tool.
I have a question regarding the code and its output. The code works but when I uncomment the one section [stack removeLastObject]; it stops working and claims the array is empty.
I don’t get this since I am removing an object from the main array — not the copies which I am using in the recursion. If I input a copy for recursion and then remove an object from the original is the copy affected?
My main example is using an array of 3, 5, + which should output (3 + 5). If I uncomment the one sections of code I get (3+3). Here is the code:
+(NSString*) descriptionTop:(NSMutableArray *) stack{
NSMutableString *programFragment = [NSMutableString stringWithString:@""];
id topOfStack = [stack lastObject];
if (topOfStack) [stack removeLastObject];
NSLog(@"operation is %@", topOfStack);
NSLog(@"Stack is%@", stack);
if([ topOfStack isKindOfClass:[NSNumber class]]){
[programFragment appendFormat:@"%g", [topOfStack doubleValue]];
}
else if( [topOfStack isKindOfClass:[NSString class]])
{
NSString *operation = topOfStack;
if ([operation isEqualToString:@"+"] ||
[operation isEqualToString:@"-"] ||
[operation isEqualToString:@"/"] ||
[operation isEqualToString:@"*"]) {
NSMutableArray *operand1 = [stack mutableCopy];
[operand1 removeLastObject];
NSMutableArray *operand2 = [stack mutableCopy];
// [stack removeLastObject];
[programFragment appendFormat:@"(%@ %@ %@)", [self descriptionTop:operand1], operation, [self descriptionTop:operand2]];
}
}
NSLog(@" program fragment returns %@", programFragment);
return programFragment;
}
I think I understand what you’re trying to do, but your logic is rather muddled. Let’s walk through your code for the input
[3 5 +](where+is the top of the stack), assuming your extra[stack removeLastObject]is uncommented. First, you (correctly) pop the operator from the stack:Then you find that
topOfStackis a string, so you assign it tooperation. Then you do this:Notice that at this point, the 5 is gone entirely! You don’t have it in any of your variables. So when you set up
operand2, the3is on top (and in fact is the only element):Now, let’s rewind to where we set up
operand1, but remove the extra[stack removeLastObject]:Now
operand2has5at the top, so the recursive call todescriptionTop:onoperand2finds the5, and you get a correct answer(3 + 5)for[3 5 +].But this function is still broken.
Consider the input
[3 4 5 * +]. What’s the correct output? I think it should be(3 + (4 * 5)). But what does your function do? Let’s walk through it. First, it pops the+operator:Next it copies the stack to
operand1and removes the last element fromoperand1:Then, assuming we don’t do
[stack removeLastObject], it copies the stack tooperand2:Now you can see that when we recursively call
descriptionTop:onoperand1here, it’s going to return5. And when we call recursively calldescriptionTop:onoperand2, it’s going to return4 * 5. So we return(5 + (4 * 5)). What happened to the3? We never reached it!The problem here is that, to reach the
3, we have to consume the4 5 *from the stack as one operand, and then look for the other operand in that same stack (where4 5 *has been consumed) so that we can find the3.What you need to do is not copy the stack at all! You need to pass the same stack object to your recursive calls, so that when you pop all of the elements that form one operand, you can find the elements for the other operand at the top of the stack. Like this: