目的: 中缀表达式转为前缀表达式(简单版), 操作数都是字符且只有一个, 运算都是普通的四则运算, 不支持负数运算.
思路: 网上已经好多了, 我也只是自己写一写加深印象→ →~~~
1. 存两个堆栈, 一个存放操作数, 一个存放操作运算符
2. 由于要转换为前缀运算, 运算符在操作数前, 所以扫描从中缀表达式的右往左扫描.
3. 如果是操作数, 则直接push进操作数堆栈
4. 如果是运算符, 分以下情况:
a.运算符堆栈为空, 或者运算符栈顶元素为')', 则直接将运算符压进栈
b.运算符如果是'(', 则将运算符栈中的元素都压进去操作数栈中并将其弹出运算符栈, 直到遇到')'为止
c. 运算操作符是'+' '-' '*' '/' 之一的时候, 将其与运算符栈顶元素作比较, 如果优先级相同, 或者栈顶的优先级较小, 则将运算符压入栈中.
否则, 将栈顶元素弹出并压入操作数栈中, 然后继续比较栈顶, 直到运算符被压入栈.
5. 扫描完一遍后, 将运算符剩余的元素都压入操作数栈中.
6. 将操作数栈从栈顶到栈底输出就是前缀表达式.
Program environment:
OS: Ubuntu 14.04 32 bits
IDE: Eclipse
Language: C++
Compiler: g++
Input & Output:
A legal infixexpression string is considered to be an input of the program,but only available for arithmetic (+, -, *, /).Enter -1 to terminate the program.
Program willprint out the prefix of the input as the result.
Ex: input: a+b*c/(d-e)
output: Prefix: +a/*bc-de
Program description:
1. Create an empty stack calledoperatorsfor keeping operators. Create an empty stack calledprefix for output.
2. Scan the inputinfix expression from right to left.
a. If the character is an operand,push it into the prefix stack.
b. If the character is an operator:
(1). If the operators stack is empty or the character is‘)’, then push the character into theoperators stack.
(2). If the character is ‘(‘, then push the top operator into prefix stack, and pop out from theoperators stack until it meets the‘)’. Do not push the ‘)’ intoprefix stack, just pop it out.
(3). If the character is one of the ‘+’, ‘-‘, ‘*’, ‘/’calledch operators stack. Repeat this step until ch meets an operator whose precedence is equal or smaller than itself, then pushch into operators stack.
3. Afterthe scan, push the rest operators of the operators stack into theprefixstack.
4. Printingout the prefix stack from top to bottom would be the result.
//============================================================================
// Name : Sicily.cpp
// Author : Reid Chan
// Version :
// Copyright : Your copyright notice
//============================================================================
#include <iostream>
#include <string>
#include <cctype>
#include <stack>
using namespace std;
bool smaller(char fix, char top)
{
if (fix == '+' || fix == '-') {
if (top == '*' || top == '/')
return true;
}
return false;
}
int main()
{
string infix;
stack<char> operators;
stack<char> prefix;
while (cin >> infix && infix != "-1") {
int len = infix.length(); // input the infix expression
char ch;
/***** scan the infix expression from right to *****
***** left to generate the prefix expression *****/
for (int i = len - 1; i >= 0; --i) {
ch = infix[i];
if(isalpha(ch)) { // if is operand, just push into prefix stack
prefix.push(ch);
} else { // else there're three situations:
char oprand;
if (operators.empty() || ch == ')') { // 1. if operator's stack is empty or ch is ")'
operators.push(ch); // just push into operators' stack
} else if (ch == '(') {
oprand = operators.top();
while (oprand != ')') { // 2. if ch is '(', push the operator into
prefix.push(oprand); // prefix's stack and pop out until it meets ')'
operators.pop();
oprand = operators.top();
}
operators.pop();
} else { // 3. compare the top operator to ch
oprand = operators.top(); // if ch's precedence is smaller,
while (smaller(ch, oprand)) { // then push the operator into
prefix.push(oprand); // the prefix's stack and pop out
operators.pop(); // until both operators' precedence is equal.
if (!operators.empty()) {
oprand = operators.top();
} else {
break;
}
}
operators.push(ch);
}
}
}
/***** push the rest operators into the stack of prefix *****/
while (!operators.empty()) {
prefix.push(operators.top());
operators.pop();
}
/***** print out the prefix expression *****/
cout << "Prefix: ";
while (!prefix.empty()) {
cout << prefix.top();
prefix.pop();
}
cout << endl;
}
return 0;
}