0

CS学生在这里。我希望能够获取诸如“2+2*3/2-2”之类的字符串并对其进行评估(= 3)。但我不确定如何构造代码以遵循正确的操作顺序。这是乘法和除法的代码:

int r = 1;
    int n = 0;
    char op = '*';

    for (int i = 0; i < E.length(); i++)
        if (E.charAt(i)=='*'||E.charAt(i)=='/')
        {
            if (op == '*')
                r *= n;
            else
                r /= n;
            n = 0;
            op = E.charAt(i);
        }
        else
            n = n*10 + (E.charAt(i)-'0');

    if (op == '*')
        r *= n;
    else
        r /= n;

    return r;

谢谢阅读!

4

4 回答 4

2

使用二叉树,其中每个节点都是算术运算符,叶子是值。

于 2013-11-07T22:39:33.350 回答
0

使用逆波兰表示法以“计算友好”的形式表示您的公式。您可以在此处阅读有关 RPN 的信息:http ://en.wikipedia.org/wiki/Reverse_Polish_notation

您的 2+2*3/2-2 的 RPN 版本将是 2 2 3 * 2 / 2 - +

然后算法是这样的:假设来自 RPN 版本的每个符号都是符号数组中的一个元素。您从数组中取出元素,如果这是一个数字,则将其放入堆栈,如果这是一个运算符,则从堆栈中取出两个元素并执行操作。结果应该再次落在堆栈上。重复直到到达数组的最后一个元素。最后,您的堆栈中只有一个元素是您的答案。

让我们可视化:迭代#符号堆栈内容 1# 2 -> 2 2# 2 -> 2,2 3# 3 -> 3,2,2 4# * -> 6,2 5# 2 -> 2,6,2 6# / -> 3,2 7# 2 -> 2,3,2 8# - -> 1,2 9# + -> 3

于 2013-11-07T23:12:34.500 回答
0

您需要解析表达式。一个简单的递归下降解析器可以做到这一点:

double expression(const char **p) {
    double rv = term(p);
    while (**p) {
        if (**p = '+') {
            ++*p;
            rv += term(p)
        } else if (**p = '-') {
            ++*p;
            rv -= term(p);
        } else
            break; }
    return rv; }

double term(const char **p) {
    double rv = factor(p);
    while (**p) {
        if (**p = '*') {
            ++*p;
            rv *= factor(p)
        } else if (**p = '/') {
            ++*p;
            rv /= factor(p);
        } else
            break; }
    return rv; }

double factor(const char **p) {
    return strtod(p, (char **)&p);
}

当然,上面不会处理字符串中的空格、括号或其他你可能关心的东西,但它们可以相对容易地添加。

于 2013-11-07T23:58:00.340 回答
0

这正是解释器模式的目的。您的数学运算基本上是一种语法 - 您需要做的就是表示该语法。使用解释器模式来解析您的数学语句,然后使用它吐出的内容来执行必要的操作。

于 2013-11-07T22:40:37.313 回答