c++中前缀表达式的递归求值

Recursive evaluation of prefixed expression in C++

本文关键字:递归 表达式 前缀 c++      更新时间:2023-10-16

我试图在c++中编写递归算法,评估类型的表达式:"操作符" "变量" "变量"并返回操作(示例:input = + 3 4;输出= 7)。操作符仅为基本操作符(+,-,*,/),变量为1到9之间的整数。问题是我不知道怎么开始,用什么方法。我不能使用堆栈或列表。

编辑:我正在为c++入门考试而学习,所以我不允许使用任何复杂的方法来解决问题,我只能使用过程,循环,递归,搜索和线程方法。

谢谢。

由于您(显然)只处理二进制操作符,因此这是相当微不足道的(有一点需要注意:尽管它不会显式地使用堆栈,但几乎任何相同的递归实现都会隐式地使用堆栈)。

基本模式看起来像这样:

int apply(char op, int a, int b) {
    switch (op) { 
       case '+': return a + b;
       case '-': return a - b;
       case '/': return a / b;
       case '*': return a * b;
       default: throw bad_operator(op);
    }
}   
int expression(char *&input) {
    char op = *input++;
    if (isdigit(op)) 
       return op - '0';
    int a = expression(input);
    int b = expression(input);
    return apply(op, a, b);
}

快速测试程序:

#include <ctype.h>
#include <iostream>
#include <exception>
#include <string>
struct bad_operator : public std::logic_error { 
    bad_operator(char ch)  : 
        std::logic_error(std::string("Bad operator: ") + ch) 
    {}
};
int main() {
    char *input="+/42-43";
    std::cout << expression(input);
    return 0;
}

试试这样做。伪代码:

double Process(Parser & parser)
{
    Token token = parser.GetToken();
    if (token.Type == number)
        return (NumberToken)token.value;
    else if (token.Type == operator)
    {
        double left = Process(parser);
        double right = Process(parser);
        switch (OperatorToken)token.op:
        {
        case '+' :
            {
                return left + right;
            }
        // ...
        }
    }
}
这类问题使用stack更容易解决。

这是一个使用递归的解决方案(表达式中不允许有空格):

#include <cstdio>
int eval(const char *s, const char **outptr)
{
    int a, b, y;
    const char *out;
    switch (*s) {
    case '+':
        a = eval(s + 1, &out);
        b = eval(out, &out);
        y = a + b;
        *outptr = out;
        break;
    case '-':
        a = eval(s + 1, &out);
        b = eval(out, &out);
        y = a - b;
        *outptr = out;
        break;
    case '*':
        a = eval(s + 1, &out);
        b = eval(out, &out);
        y = a * b;
        *outptr = out;
        break;
    case '/':
        a = eval(s + 1, &out);
        b = eval(out, &out);
        y = a / b;
        *outptr = out;
        break;
    default: /* '0'...'9'assumed */
        y = *s - '0';
        *outptr = s + 1;
        break;
    }
    return y;
}
int main(int argc, char *argv[])
{
    const char *end;
    int x;
    x = eval(argv[1], &end);
    printf("%dn", x);
    return 0;
}

的例子:

./eval +3+*45/62
26

假设你有一个输入迭代器(例如,一个指向输入字符串的指针或一个向量迭代器),你可以这样使用:

compute (input.iterator it) {
  if (it != input.end() and is_operator(*it)) {
     operator op = *it;
     int v1, v2;
     it++;
     v1 = is_operator(*it) ? compute(it) : *it;
     it++;
     v2 = is_operator(*it) ? compute(it) : *it;
     return operator_exec(op, v1, v2) 
  }
  return *it;
}