题目描述:
Add the capability to yourCalculatorBrainto accept variables as operands (in addition to still acceptingdoubles as operands). You will need new public API in yourCalculatorBrainto support this.
A variable will be specified as anNSStringobject. To simplify your implementation, you can ignore attempts to push a variable whose name is the same as an operation (e.g. you can ignore an attempt to push a variable named “sqrt”).
The values of the variables will only be supplied when the “program” is “run.” You must add a new version of therunProgram:class method with the following signature ...
+ (double)runProgram:(id)program usingVariableValues:(NSDictionary*)variableValues;
The keys in the passedvariableValuesdictionary areNSStringobjects corresponding to the names of variables used in the passedprogram, and the values in the dictionary areNSNumberobjects specifying the value of the corresponding variable (for this assignment we will supply “test” values, see Required Task #3).
If there are variables in the specifiedprogramfor which there are no values in the specifiedNSDictionary, use a value of 0 for those variables when you run the program. This should be the case if someone calls the originalrunProgram:method (the one shown in the demo in class).
In addition, create another class method to get all the names of the variables used in a givenprogram(returned as an NSSetofNSStringobjects) ...
+ (NSSet*)variablesUsedInProgram:(id)program;
If the program has no variables return nilfrom this method (not an empty set).
在正式编写runProgramUsingVariables函数之前, 我们需要写一个pushVariable函数,就像之前的pushOperand一样。用来关联以后的按键事件。非常简单
(void) pushVariable:(NSString *)variableName
{
[self.programStack addObject:variableName];
}
+(NSSet *) variableUsedInProgram:(id)program
{
NSMutableSet *result = [NSMutableSet setWithCapacity:3];
if ([program containsObject:@"x"])
{
[result addObject:@"x"];
}
if ([program containsObject:@"y"])
{
[result addObject:@"y"];
}
if ([program containsObject:@"foo"])
{
[result addObject:@"foo"];
}
if ([result count] == 0) {
return nil;
}
else return [result copy];
}
这个函数返回一个NSSet类,告诉我们这个program中都使用了哪些变量。无非就是遍历整个堆栈,有变量就放到nsset里。这里要注意的就是nsset类方法的使用.
[NSSet setWithCapacity:int]
[foo addObject:Obj]
+(double) runProgram:(id)program
usingVariableValues:(NSDictionary *)variableValues
{
NSMutableArray *stack;
if ([program isKindOfClass:([NSArray class])])
{
stack = [program mutableCopy];
}
for (int i = 0; i < [stack count]; i++) {
id item = [stack objectAtIndex:i];
if ([item isKindOfClass:[NSString class]] &&
([item isEqualToString:@"x"] ||
[item isEqualToString:@"y"] ||
[item isEqualToString:@"foo"]))
{
[stack replaceObjectAtIndex:i withObject:[variableValues objectForKey:item]];
}
}
return [self popOperandOffStack:stack];
}
@synthesize variableValues = _variableValues;
-(NSMutableDictionary *) variableValues
{
if ( _variableValues == nil)
{
NSNumber *zero = [NSNumber numberWithDouble:0];
NSArray *zeros = [NSArray arrayWithObjects:zero, zero, zero, nil];
NSArray *variableNames = [NSArray arrayWithObjects:@"x", @"y", @"foo", nil];
_variableValues =[[NSMutableDictionary alloc] initWithObjects:zeros forKeys:variableNames];
}
return _variableValues;
}
我不知道这是不是好方法,但确实可以用。。。而且自己看起来也蛮顺眼![敲打](http://static.blog.csdn.net/xheditor/xheditor_emot/default/knock.gif)
-(double) performOperation: (NSString *)operation
{
[self.programStack addObject:operation];
if ([CaculatorBrain variableUsedInProgram:self.program]) {
return [CaculatorBrain runProgram:self.program usingVariableValues:self.variableValues];
}
else return [CaculatorBrain runProgram:self.program];
}
![偷笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
![睡觉](http://static.blog.csdn.net/xheditor/xheditor_emot/default/sleep.gif)