从左到右在Objective-C中解决简单的数学表达式

4

我在objective c中有这个表达式NSString: @"10+5*2"。 我希望自动解决这个表达式,然后发现了一个解决方案:

UIWebView *webView = [[UIWebView alloc] init];
NSString *result = [webView stringByEvaluatingJavaScriptFromString:expression];
NSLog(@"%@",result); 

上述方法很好,但会产生结果:20。实际上,这个表达式首先计算 "*",即 5*2 = 10 + 10。但我想消除这种优先级,使每个运算符从左到右具有相同的优先级,以便答案为 10+5 = 15 * 2 = 30。
虽然编写自己的函数是最后的选择,但我真的不想搞乱字符串函数。我想使用一些内置的东西。
谢谢,
**工作解决方案**
感谢 Eiko 和 Ozair 的所有帮助!根据他们的答案,我编写了这一堆代码,对我来说完美无缺!
NSString *expression = lblBox.text; // Loads the original expression from label.
    expression = [expression stringByReplacingOccurrencesOfString:@"+" withString:@")+"];
    expression = [expression stringByReplacingOccurrencesOfString:@"-" withString:@")-"];
    expression = [expression stringByReplacingOccurrencesOfString:@"*" withString:@")*"];
    expression = [expression stringByReplacingOccurrencesOfString:@"/" withString:@")/"];


    NSUInteger count = 0, length = [expression length];
    NSRange range = NSMakeRange(0, length); 

    while(range.location != NSNotFound)
    {
        range = [expression rangeOfString: @")" options:0 range:range];
                 if(range.location != NSNotFound)
                 {
                     range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
                     count++; 
                 }
    }

    for (int i=0; i<count; i++) {
        expression = [@"(" stringByAppendingString:expression];
    }


    UIWebView *webView = [[UIWebView alloc] init];
    NSString *result = [webView stringByEvaluatingJavaScriptFromString:expression];
    [webView release];
    NSLog(@"%@ = %@",expression, result);

你能修改这个字符串吗?还是它来自用户或另一个系统? - Ozair Kafray
1
使用括号怎么样? - marzapower
1
如果你想更深入地了解数学表达式求值,这个人已经深入研究了http://funwithobjc.tumblr.com/post/6196535272/parsing-mathematical-expressions - tsakoyan
1
在构建字符串时,为什么不直接进行计算? - Eiko
1
你可能需要重新考虑添加括号,因为没有内置的方法可以忽略优先级进行评估,但如果你正在构造该字符串,则很容易同时构造一个带有括号的字符串,以强制从左到右进行评估。 - andyvn22
显示剩余4条评论
3个回答

6

不确定是否与@Ozair Kafray所说的相同...

对于每个追加到字符串的运算符,先添加),并在开头添加匹配的(。例如:

10
(10 ) +
(10 ) + 5
((10 ) + 5 ) *
((10 ) + 5 ) * 2

在删除操作符时,请确保同时删除括号。


我希望一旦字符串形成,就有一种方法可以做到这一点。有吗? +1 举例说明! - necixy
如果您不想并行构建,可以将每个运算符替换为“)运算符”,然后在开头添加相应数量的“(”。如果只有几个可用的运算符,并且通过比较字符串长度来获取运算符数量,则可能很容易实现。 - Eiko
太棒了! 你很厉害! 只是想找出如何获取字符串中运算符的数量。 不过这是另一回事了。 谢谢。 - necixy
很简单。比较原始字符串的长度和替换为“)运算符”后的长度。每次替换只会增加一个字符。 - Eiko
1
+1 是真的很好的说明。虽然我的答案是一样的,但我在想着如何进行说明,因为我不太会用 Objective-C 编写代码。结果证明,我并不需要知道 Objective-C 就能得到一个被接受的答案。 - Ozair Kafray
显示剩余2条评论

3

我不知道有没有内置的方法来实现这个功能。我认为你只能自己动手写一个函数。如果你想使用Objective-C,那么可以使用NSScanner。


谢谢您的回复! 您能否帮我了解一下NSScanner是如何工作的,以及它在什么情况下会有帮助? - necixy
一如既往地,苹果的文档比我讲得更好:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/Scanners.html#//apple_ref/doc/uid/20000147-BCIEFGHC - sosborn

3
根据您在评论中的回答,您是在输入期间生成字符串。我建议在每个操作数后面(第一个除外)添加括号。
因此,在10之后不需要向字符串添加任何内容,然后添加运算符+。对于每个操作数5,在字符串开头添加一个相应的开括号(和一个结束括号)。类似地,在2之后也要这样做。这样,您就不必自己编写处理字符串的代码了。

太棒了!但是我也使用了删除键,因此在编写时,我认为这个括号的东西可能会导致问题,因此我希望它在字符串编写完成后再进行。我希望有一种方法可以在字符串完成后执行这个括号的工作。 - necixy
不需要特殊处理第一个运算符。这只会增加不必要的代码复杂性。 - Eiko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接