9

我想在 iOS 中求解一个条件方程:

我从数据库中得到的方程是 NSString 格式的,例如:

if((height > 0), (weight+ 2 ), ( weight-1 ) )

根据我们的理解,如果我解析上面的字符串和单独的height>0条件,它将是NSString格式。但是要评估它,我如何将字符串转换为条件语句?

获得条件语句后,可以通过将其转换为三元方程来求解方程,如下所示:

Bool status;

NSString *condition=@” height>0”;

If(condition)    //But condition is treated as a string and not as a conditional statement.
{
    status=True;
}
else
{
    status=False;
}

Return status ? weight+ 2 : weight-1;`

方程也可以动态变化,因此它们不能被硬编码。简而言之,我如何解决我得到的这个方程NSString

感谢您的耐心等待!

4

2 回答 2

5

DDMathParser 作者在这里...

为了扩展乔纳森的答案,您可以在 DDMathParser 中完全做到这一点。但是,要按原样解析字符串,您需要做两件事。

首先,您需要创建一个if函数:

DDMathEvaluator *evaluator = [DDMathEvaluator sharedMathEvaluator];
[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError *__autoreleasing *error) {
    if ([args count] == 3) {
        DDExpression *condition = [args objectAtIndex:0];
        DDExpression *resultExpression = nil;
        NSNumber *conditionValue = [condition evaluateWithSubstitutions:vars evaluator:eval error:error];
        if ([conditionValue boolValue] == YES) {
            resultExpression = [args objectAtIndex:1];
        } else {
            resultExpression = [args objectAtIndex:2];
        }
        NSNumber *result = [resultExpression evaluateWithSubstitutions:vars evaluator:eval error:error];
        return [DDExpression numberExpressionWithNumber:result];
    }
    return nil;

} forName:@"if"];

这将创建一个if()函数,该函数接受三个参数。根据第一个参数的评估方式,它可以评估为第二个或第三个参数的结果。

你需要做的另一件事是告诉评估者什么heightweight意思。由于它们不以$字符开头,因此它们被解释为函数,而不是变量。如果他们以 a 开头$,那么就像这样评估它一样简单:

NSString *expression = @"if(($height > 0), ($weight+ 2 ), ( $weight-1 ) )";
NSDictionary *variables = @{@"height" : @42, @"weight" : @13};
NSNumber *result = [expression evaluateWithSubstitutions:variables evaluator:evaluator error:nil];

但是,由于它们以 a 开头$,它们是函数,这意味着您需要告诉评估者函数的评估结果。height您可以通过为和创建函数来做到这一点weight,就像您为 所做的那样if

[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError **error) {
    return [DDExpression numberExpressionWithNumber:@42];
} forName:@"height"];

或者,您可以使其更具动态性并使用 的functionResolverDDMathEvaluator,这是一个返回块 (woooooo) 的块,看起来像这样:

NSDictionary *values = @{@"height": @42, @"weight": @13};
[evaluator setFunctionResolver:^DDMathFunction(NSString *name) {
    DDMathFunction f = ^(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError **error) {
        NSNumber *n = [values objectForKey:name];
        if (!n) { n = @0; }
        return [DDExpression numberExpressionWithNumber:n];
    };
    return f;
}];

有了这两个部分(注册if并提供 and 的值heightweight,您可以执行以下操作:

NSString *expression = @"if((height > 0), (weight+ 2 ), ( weight-1 ) )";
NSNumber *result = [expression evaluateWithSubstitutions:nil evaluator:evaluator error:nil];

...并取回 . 的正确结果@15

(我计划DDMathParser让未知函数回退到提供的变量值,但我还没有完成它)

于 2013-05-17T05:36:09.423 回答
4

您将不得不编写自己的解释器或找到支持这种表达方式的解释器。

第一部分(条件)可以由 评估NSPredicate。对于第二部分(计算),您将需要一些数学表达式评估。试试这个https://github.com/davedelong/DDMathParser。也许你可以同时做,DDMathParser但我不确定。

于 2013-05-16T10:39:11.037 回答