中缀表达式求前缀和后缀的三种方法

一、根据运算符的优先级加括号法

举例:中缀表达式求后缀表达式

a+b*(c-d)-e/f
  1. 根据运算符的优先级给表达式加上括号           ((a+(b*(c-d)))-(e/f))
  2.   将最外层的符号先提取到对应括号的右侧:(前缀表达式与之相反,是将运算符移动到对应括号的左侧,不再举例
  • ((a+(b*(c-d)))(e/f)) )  //相对整个表达式来讲 这个减号是最外层的运算符
  • ((a(b*(c-d)))+(ef))—  ) //从左向右这个+属于最外层
  •   ((a(b*(c-d)))+(ef)/)— )//....
  •   ((a(b(c-d))*)+(ef)/)—)//...
  •   ((a(b(cd)-)*)+(ef)/)—)//...
  • abcd-*+ef/-       //最后去掉所有的括号
  • 其实也不用管那个是属于最外层的,只要把符号移动到对应的括号右边就行

二、利用栈来求后缀表达式(求前缀表达式也一样,只不过是从右往左遍历中缀表达式,并将每次遇到的操作数或弹出的运算符写在当前操作数或运算符的左侧

中缀表达式求后缀表达式:

a+b*(c-d)-e/f
  1. 从左到右将遇到的运算符入栈,遇到操作数直接将其写下来就行
  2. 在将运算符入栈的时候先看看是否即将入栈的运算符优先级是否高于栈顶运算符的优先级,如果高则直接入,如果低,那么就进行出栈,直到栈顶的运算符优先级低于即将要入的运算符优先级,将弹出的运算符 跟在刚刚的操作数后面就行。
  3. 如果入栈的时候运算符是右括号那么就出栈,直到出栈遇到左括号再停止出栈

三、将中缀表达式画成二叉树,然后对其进行前序和后序遍历即可

  1. 先从右向左遍历中缀表达式,找到从右到左的第一个优先级最低的运算符来做二叉树的根,确定根之后那么它的左右子树基本确定,然后第二次遍历中缀表达式找第二优先级最低的运算符,然后根据刚刚的大致位置确定第二最低优先级运算符的位置

### C++ 使用栈实现中缀表达式转换为前缀和后缀表达式的算法 #### 一、基本概念 在计算机科学中,表达式可以分为三种形式:中缀表达式、前缀表达式和后缀表达式。其中: - **中缀表达式** 是人们常用的书写方式,操作符位于两个操作数之间。 - **前缀表达式** 的操作符位于其操作数之前。 - **后缀表达式** 的操作符位于其操作数之后。 为了将中缀表达式分别转化为前缀和后缀表达式,通常会借助栈这一数据结构完成运算优先级的处理[^1]。 --- #### 二、中缀到后缀的转化算法 以下是基于栈的数据结构实现中缀表达式后缀表达式的具体逻辑: 1. 初始化一个空栈用于存储操作符。 2. 遍历输入的中缀表达式字符串中的每一个字符。 3. 如果当前字符是一个操作数,则直接将其加入输出队列。 4. 如果当前字符是左括号 `(` ,则压入栈中。 5. 如果当前字符是右括号 `)` ,则依次弹出栈顶元素直到遇到对应的左括号 `( )` 并丢弃该左括号。 6. 如果当前字符是操作符(如 `+`, `-`, `*`, `/`),则比较它与栈顶操作符的优先级: - 若栈为空或者栈顶操作符优先级低于当前操作符,则将当前操作符压入栈; - 否则,持续弹出栈顶操作符至输出队列,直至满足条件再压入当前操作符。 7. 当遍历完成后,如果栈不为空,则逐一弹出剩余的操作符并加入输出队列。 ```cpp #include <iostream> #include <stack> #include <string> using namespace std; int precedence(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; return 0; // For other characters or parentheses. } bool isOperator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/'); } void infixToPostfix(string s, string &result) { stack<char> st; for (char ch : s) { if (ch >= 'a' && ch <= 'z') result += ch; // Operand found else if (ch == '(') st.push(ch); // Push to stack else if (ch == ')') { // Pop until matching ( while (!st.empty() && st.top() != '(') { result += st.top(); st.pop(); } if (!st.empty()) st.pop(); // Remove the '(' from stack } else { // Operator encountered while (!st.empty() && precedence(st.top()) >= precedence(ch)) { result += st.top(); st.pop(); } st.push(ch); } } while (!st.empty()) { // Remaining operators in stack result += st.top(); st.pop(); } } ``` 上述代码实现了从中缀表达式后缀表达式的转换功能[^2]。 --- #### 三、中缀到前缀的转化算法 对于从前缀表达式的构建,可以通过以下步骤逆向思维解决: 1. 将整个中缀表达式反转。 2. 把所有的左括号替换为右括号,反之亦然。 3. 利用标准的中缀转后缀方法得到结果后再整体翻转即可获得最终的前缀表示。 ```cpp // Helper function to reverse a string string reverseString(const string& str) { string reversedStr = ""; for (auto it = str.rbegin(); it != str.rend(); ++it) { char currentChar = *it; if (currentChar == '(') currentChar = ')'; else if (currentChar == ')') currentChar = '('; reversedStr += currentChar; } return reversedStr; } void infixToPrefix(string s, string &prefixResult) { string reversedInfix = reverseString(s); string postfixReversed; infixToPostfix(reversedInfix, postfixReversed); prefixResult = reverseString(postfixReversed); } ``` 此部分展示了如何通过简单的变换技巧来获取前缀表达式的结果。 --- #### 四、综合示例程序 下面提供了一个完整的C++程序框架,演示了如何利用栈将给定的中缀表达式同时转换成前缀和后缀两种形式。 ```cpp int main() { string infixExpression = "a+b*c+(d*e+f)*g"; string postfixResult = "", prefixResult = ""; infixToPostfix(infixExpression, postfixResult); cout << "Postfix Expression: " << postfixResult << endl; infixToPrefix(infixExpression, prefixResult); cout << "Prefix Expression: " << prefixResult << endl; return 0; } ``` 运行以上代码将会打印出相应的前后缀版本作为验证依据。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值