有效编码的最佳方法是什么,因为这将被递归调用,并且创建大量对象并不好。 +*-/, sin,cos,sqrt,pi and x,y,a,b
应该放在三个独立的if statements
中,而不像现在所有的一切都是分开的。同样为了便于阅读,制作包含4 isEqualToString
的if语句并不是很好。
NSString *operation = topOfStack;
if ([operation isEqualToString:@"+"]) {
} else if ([@"*" isEqualToString:operation]) {
} else if ([operation isEqualToString:@"-"]) {
} else if ([operation isEqualToString:@"/"]) {
} else if ([operation isEqualToString:@"sin"]) {
} else if ([operation isEqualToString:@"cos"]) {
} else if ([operation isEqualToString:@"sqrt"]) {
} else if ([operation isEqualToString:@"pi"]) {
} else if ([operation isEqualToString:@"x"]) {
} else if ([operation isEqualToString:@"y"]) {
} else if ([operation isEqualToString:@"a"]) {
} else if ([operation isEqualToString:@"b"]) {
}
答案 0 :(得分:3)
我不相信有最佳方法可以做到这一点,但这里有另一个选项来补充已经给出的答案。
创建一个NSDictionary,将您的操作名称(sin,sqrt, - )映射到选择器,如下所示:
NSDictionary *operations = @{
@"sin": [NSValue valueWithPointer:@selector(operationSin:)],
/* other operations here */
};
然后你的switch语句变成了查找。
NSString *operation = topOfStack;
if(operations[operation]) {
SEL op = [operations[operation] pointerValue];
[self performSelector:op withObject:value]; /* Or some approximation thereof */
}
else {
/* Default action for unknown operation */
}
或者,您可以在已识别的操作上创建枚举,使用NSDictionary将操作名称映射到装入枚举值的NSNumber。
typedef NS_ENUM(NSUInteger, OperationType) {
OperationTypeSin = 0L,
OperationTypeSqrt,
/* and so on */
OperationTypeUnknown
};
/* And later... */
NSDictionary *operations = @{
@"sin": @(OperationTypeSin),
/* you get the idea */
};
/* Finally ... */
NSString *operation = topOfStack;
OperationType opType = [operations[operation] unsignedIntegerValue];
switch(opType) {
case OperationTypeSin:
/* Much cleaner, and type-safe too */
}
答案 1 :(得分:2)
<强>的制备:
强>
首先将NSString操作转换为int哈希码,将该哈希码存储在#define中
或不变。
<强>代码:强>
1)将NSString操作转换为int哈希码(tokenId) 2)然后在 tokenId 上执行switch语句。
int token = operationToToken(operation);
switch (token) {
case: OP_MINUS: break;
case: OP_SIN: break;
case: OP_COS: break;
}
答案 2 :(得分:1)
首先,可能会回退到C字符串,然后利用sin
,cos
,sqrt
,pi
,a
,{{ 1}},b
和x
(差不多)都以不同的字符开头:
y
答案 3 :(得分:1)
如果你正在使用Objective-C,那么你可以用一些巧妙命名的选择器来做到这一点。
首先,创建一个对象来封装Operation
。
然后,创建一个-initWithOperation:(NSString *)op
方法。在此方法中,将任何符号操作(*
,+
等)转换为唯一的字符串标识符(仅限字母)。
然后,您可以调用NSSelectorFromString(stringOp)
,但如果您希望方法有参数,则必须自己附加:
个字符。
拥有选择器后,您可以使用-performSelector:
,+performSelector:
执行选择器,或手动调用选择器。
如果您使用与操作相同的名称命名每个选择器,则不需要任何if
或switch
语句,但您必须处理发送无效选择器的情况
E.g:
@interface Operation : NSObject
- (id)initWithOperation:(NSString *)op;
- (void)performOperationWithValue:(float)value;
+ (float)sin:(float)value;
// ... Other operations
@property (nonatomic, copy) NSString *theOperation;
@end
@implementation Operation
- (id)initWithOperation(NSString *)op {
self = [super init];
if (self) {
// Convert symbols to unique strings
theOperation = [[NSString alloc] initWithString:op];
}
return self;
}
- (void)performOperationWithValue:(float)value {
NSString *withOneParam = [self.theOperation stringByAppendingString:@":"];
SEL sel = NSSelectorFromString(withOneParam);
[Operation performSelector:withOneParam withObject:[NSNumber numberWithFloat:value]];
}
// Class methods are the actual operation implementation...
在上面的示例中,我假设您已将@"sin"
传递给Operation
对象。这只能在Objective-C中实现,因为您可以利用命名选择器。
答案 4 :(得分:0)
您可以为每个符号分配一个数字,并可以实现切换案例。