2

これを効率的にコーディングする最善の方法は、これが再帰的に呼び出されるため、多くのオブジェクトを作成するのは良くありません。すべてが分離されている現在とは異なり+*-/, sin,cos,sqrt,pi and x,y,a,b、3 つに分離する必要があります。if statementsまた、読みやすさのために、4 を含む if ステートメントを作成することisEqualToStringはあまり良くありません。

    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"]) {

    }
4

5 に答える 5

3

これを行う最善の方法があるとは思いませんが、既に与えられた回答を補足する別のオプションがあります。

次のように、操作名 (sin、sqrt、-) をセレクターにマップする NSDictionary を作成します。

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 */
}
于 2013-01-30T18:22:34.700 に答える
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;

}
于 2013-01-30T18:10:06.487 に答える
1

Objective-C を使用している場合は、巧妙な名前のセレクターを使用してこれを行うことができます。

まず、カプセル化するオブジェクトを作成しますOperation

次に、-initWithOperation:(NSString *)opメソッドを作成します。このメソッド内で、シンボル操作 ( 、 など) を一意の文字列識別子 (文字のみ) に変換し*ます+

次に、メソッドに引数を持たせたい場合は、自分で文字NSSelectorFromString(stringOp)を追加する必要がありますが、呼び出すことができます。:

セレクターを取得したら、 、 を使用してセレクターを実行する-performSelector:+performSelector:、セレクターを手動で呼び出すことができます。

各セレクターに操作と同じ名前を付ける場合、iforswitchステートメントは必要ありませんが、無効なセレクターを送信する場合を処理する必要があります。

例えば:

@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 でのみ可能です。

于 2013-01-30T23:34:29.467 に答える
1

sinまず、おそらく C 文字列にフォールバックし、cossqrtpiabxおよびy(ほとんど) すべてが異なる文字で始まるという事実を利用します。

const char *s = [operation UTF8String];
switch (s[0]) {
case '+':
    // addition
    break;
case '-':
    // subtraction
    break;
case 's':
    // sine or sqrt
    switch (s[1]) {
    case 'q':
        // sqrt
        break;
    case 'i':
        // sine
        break;
    }
    break;
case 'c':
    // cosine
    break;
// et cetera...
default:
    // not found
}
于 2013-01-30T18:07:24.607 に答える
0

各シンボルに番号を割り当て、スイッチケースを実装できます。

于 2013-01-30T18:06:15.513 に答える