Thanks Lee!
using Obj-C, By the way.
Your input will likely be NSStrings instead of char *, then. The logic is pretty much the same, though.
Code:
NSMutableArray *inputTokens = nil;
inputTokens = [inputBuffer componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
while([inputTokens count] > 1) { When we are down to one item it should be our result
if([myRPNClass isNumeric:[inputTokens lastObject]]){ //isNumeric would have to be defined to take an NSString * and return true/false
NSLog(@"Error. Invalid RPN equation entered.");
//exit, return, whatever
} else {
[MyRPNClass performSingleOperation:inputTokens]; //This method does the real work
}
}
if([myRPNClass isNumeric:[inputTokens lastObject]]) {
NSLog(@"The result is: %d",[[inputTokens lastObject] intValue]);
} else {
NSLog(@"Parse error.");
}
...
+ (void) performSingleOperation:(NSArray *)inputTokens {
NSString *operator = [inputTokens lastObject];
[inputTokens removeLastObject]; //pop
int op;
if([operator isEqualToString:@"+"]) {
op=OP_PLUS;
} elseif { //Fill in all other operator cases
...
}
if(![myRPNClass isNumeric:[inputTokens lastObject]) { //non-numeric
[myRPNClass performSingleOperation:inputTokens];
}
int operandA = [[inputTokens lastObject] intValue];
[inputTokens removeLastObject]; //pop
if(![myRPNClass isNumeric:[inputTokens lastObject]) { //non-numeric
[myRPNClass performSingleOperation:inputTokens];
}
int operandB = [[inputTokens lastObject] intValue];
[inputTokens removeLastObject]; //pop
switch(op) {
case OP_PLUS:
[inputTokens addObject:[NSString initWithFormat:@"%d",operandA + operandB]];
break;
... //One case for each operator
}
return;
}
+ (BOOL) isNumeric:(NSString *)toCheck { //There may be a better way to do this, but it was the best i could come up with
if([toCheck intValue] != 0) {
return true;
} else if([toCheck isEqualToString:@"0"]) {
return true;
} else {
return false;
}
}
I didn't compile this, but I'm pretty confident in the various NSString and NSMutableArray methods used. Since I didn't try it myself, the logic may be a bit off. This essentially uses an NSMutableArray as a stack. It keeps all of the operators and operands on the same stack. I didn't use any NSNumber *s as intermediate storage for actual integer values. It seemed just as well to keep them in strings. The "main" routine doesn't do much, performSingleOperation does the work, calling itself recursively if needed. When the while() loop in the main function completes the single member on the stack should be the result. You can use intValue to get the actual int.
This also assumes only binary operations. Something like taking the negative of a number, or the square root, would need to be written as x -1 * and x .5 ^ instead of the implicit use normally seen with these operations. I guess this is always the case in RPN, but I can't say that I am intimately familiar with it.
-Lee
Edit: I just realized that in the "main" method you should only make a call to performSingleOperation once, if the RPN is formatted properly. The while should really just be collapsed to an if(count > 1), and inside that an if(isNumeric). I don't feel like changing it, but that just occurred to me.