【问题标题】:Infix to Prefix Conversion using Recursion使用递归的中缀到前缀转换
【发布时间】:2017-03-08 14:56:55
【问题描述】:

我正在努力寻找前缀翻译方案的中缀。

我已经找到了后缀翻译方案的中缀:

expr -> Term, Rest
Rest -> +Term, { print('+') } , Rest | -Term, { print('-') }, Rest | epsilon
Term -> Factor, Rest_
Rest_ -> *Factor, { print('*') }, Rest_ | /Factor, { print('/') }, Rest_ | epsilon
Factor -> Digit | (expr)
Digit -> 0,1,2,3,4,5,6,7,8,9

和我的中缀到后缀的转换代码按照上面的翻译方案:

#include<iostream>

using namespace std;

const char input[] = "9-5*2";
int index = 0;
char LookAhead = input[index];

void Match(char newChar);
void Factor();
void Rest_();
void Rest();
void Term();
void Expression();


int main(){
    Expression();
    return 0;
}

void Match(char newChar){
    if(newChar == LookAhead){
        index++;
        LookAhead = input[index];
    }
}

void Expression(){
    Term();
    Rest();
}

void Term(){
    Factor();
    Rest_();
}

void Rest(){
    if(LookAhead == '+'){
        Match('+');
        Term();
        cout << '+';
        Rest();
    }else if(LookAhead == '-'){
        Match('-');
        Term();
        cout << '-';
        Rest();
    }else{

    }
}

void Rest_(){
    if(LookAhead == '*'){
        Match('*');
        Factor();
        cout << '*';
        Rest_();
    }else if(LookAhead == '/'){
        Match('/');
        Factor();
        cout << '/';
        Rest_();
    }else{

    }
}

void Factor(){
    if(isdigit(LookAhead)){
        cout << LookAhead;
        Match(LookAhead);
    }
}

所以现在有没有高手可以帮我理解中缀到前缀转换的翻译方案,不胜感激。

我们可以通过解析树进行测试。如果我们可以从示例字符串 9-5+2 生成类似 -9+52 前缀字符串。

如果我需要解释更多关于我的中缀到后缀转换的翻译方案和代码以便更好地理解,请告诉我。

提前致谢!

已编辑: 只是我在找出前缀表达式转换翻译方案的中缀时遇到问题。举个例子, 我的意见:

9-5+2

预期输出:

-9+52

我想用我上面展示的相同结构来实现这一点,通过中缀到后缀的转换。 就是这样!

【问题讨论】:

  • 您的代码是否可以正常工作,而您只需要代码审查?然后在codereview.stackexchange.com 上发帖。如果它不起作用,那么您需要详细说明您的问题(例如向我们展示一些特定的输入、预期和实际输出,以及您尝试调试问题的内容)。如果你已经完成了,那么请花点时间read about how to ask good questions
  • 搜索反向波兰表示法
  • @EdHeal 你能详细说明一下吗
  • @Ray Just google。
  • 谷歌一下。将中缀转换为后缀。可以找到算法来做到这一点

标签: c++ compiler-construction parse-tree


【解决方案1】:

最简单的解决方案是在解析时构造一个Abstract Syntax Tree (AST),然后使用preorder traverse 递归遍历树。

您也可以随时构造字符串(例如建议here by @ChrisDodd),但是:

  • 这不是递归解决方案 :),并且
  • 它涉及大量的字符串复制,因此它可能会有二次运行时间。

将后缀转换为某种临时数据结构(例如堆栈)似乎也很诱人,然后通过打印前缀表达式递归地遍历后缀表示“评估”。这肯定会起作用,但是您会遇到这样的问题,即以自然方式遍历后缀表示将首先访问每个表达式的 right-hand 参数,而您首先想要的是 左手 论点。这意味着您需要向后构造字符串,这涉及另一个临时数据结构(例如另一个堆栈)。

总体而言,AST 解决方案更干净,为以后添加更多功能提供了良好的基础。

【讨论】:

  • 我遵循了递归方式,只是使用了时间存储概念,并在我想做的事情上取得了成功,请在此处查看我的答案,感谢您的帮助!
  • @Ray:我想你已经用比9-5+2 更复杂的表达式测试了它,对吧?我很难相信单个临时值足以存储整个未打印值堆栈。 1*2+3*4 是否正确输出 +*12*34?我想您似乎没有解析括号这一事实限制了表达式的复杂性,但除非要求明确,否则这似乎是一个巨大的遗漏。无论如何,祝你好运。
【解决方案2】:

所以我使用了一个时间变量来存储我的数字,并在保持订单优先级的情况下递归地检查和打印运算符。

我的解决方案:

#include<iostream>

using namespace std;

const char input[] = "9-5+2";
int index = 0;
char LookAhead = input[index];
char TempLookAhead = 'x';

void Match(char newChar);
void Factor();
void Rest_();
void Rest();
void Term();
void Expression();


int main(){
    Expression();
    return 0;
}

void Match(char newChar){
    if(newChar == LookAhead){
        index++;
        LookAhead = input[index];
    }
}

void Expression(){
    Term();
    Rest();
    cout << TempLookAhead;
}

void Term(){
    Factor();
    Rest_();
}

void Rest(){
    if(LookAhead == '+'){
        cout << '+';
        cout << TempLookAhead;
        Match(LookAhead);
        Term();
        Rest();
    }else if(LookAhead == '-'){
        cout << '-';
        cout << TempLookAhead;
        Match(LookAhead);
        Term();
        Rest();
    }else{

    }
}

void Rest_(){
    if(LookAhead == '*'){
        cout << '*';
        cout << TempLookAhead;
        Match(LookAhead);
        Factor();
        Rest_();
    }else if(LookAhead == '/'){
        cout << '/';
        cout << TempLookAhead;
        Match(LookAhead);
        Factor();
        Rest_();
    }else{

    }
}

void Factor(){
    if(isdigit(LookAhead)){
        TempLookAhead = LookAhead;
        Match(LookAhead);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多