栈应用——中缀转后缀+后缀计算

来源:互联网 发布:linux中echo命令详解 编辑:程序博客网 时间:2024/06/05 04:51

中缀表达式(infix expression)即  平时生活中大家对于算式的书写格式( eg: 6*((5+(2+3)*8)+3)  );

后缀表达式(post expression)即  把数字和运算符分开,把运算符的优先级运算内涵到后缀式的数字和运算符的顺序中(故其优点就是,没有必要知道任何优先的规则),一个运算符只对其前边的两个数字起作用( eg: 652 3+8*+3+*);


中缀转后缀:

·读入表达式,若是数字放入输出字符串;

·若是运算符,则先与栈顶元素比较:

-栈空,直接压入栈;

-否则比较优先级:(优先级顺序:当前(> *、/> +、-> 栈中 (>  ) )

~ 当前=栈顶:出栈后压入当前;

~ 当前<栈顶:出栈   至  当前=栈顶 进行处理 / 出栈,当前不进栈直接放入输出字符串;

~ 当前>栈顶:压入栈;

~ 若是 )     :出栈 至 ( 为止,但是(和)不放入输出字符串。

时间复杂度: O(N)


代码如下:(智障的我只想到了各种if,然后括号只有 () ,运算符只有 +-*/ )


string infixTOpostfix(const string s){string post_s;stack mark;for (size_t i = 0; i < s.length(); ++i) {if (isalnum(s[i]))post_s.push_back(s[i]);else {if (mark.empty()) {mark.push(s[i]);}elseswitch (s[i]) {case '+':case '-':if (mark.top() == '*' || mark.top() == '/') {while (mark.top() == '*' || mark.top() == '/') {post_s.push_back(mark.top());mark.pop();}if (mark.top() == '+' || mark.top() == '-') {post_s.push_back(mark.top());mark.pop();mark.push(s[i]);}elsemark.push(s[i]);}else if (mark.top() == '+' || mark.top() == '-') {post_s.push_back(mark.top());mark.pop();mark.push(s[i]);}else mark.push(s[i]);break;case '*':case '/':if (mark.top() == '*' || mark.top() == '/') {post_s.push_back(mark.top());mark.pop();}mark.push(s[i]);break;case '(':mark.push(s[i]);break;case ')':while (mark.top() != '(' && !mark.empty()) {post_s.push_back(mark.top());mark.pop();}mark.pop();break;default:    break;}}}while (!mark.empty()) {post_s.push_back(mark.top());mark.pop();}return post_s;}


后缀计算:

·见到数字时,压入栈;

·见到运算符时,从栈中弹出两个数  second 运算符 first,后再压入栈;


时间复杂度: O(N)


代码如下:(开始总不对,才意识到,char的数字转换成int,是需要  - ‘0’,得到的时和0,相差的ascii码数值)


int postfixCompute(const string s){int temp1, temp2;stack result;for (size_t i = 0; i < s.length(); ++i) {if (isdigit(s[i]))//与0的ascll码运算result.push(s[i] - '0');else {temp1 = result.top();result.pop();temp2 = result.top();result.pop();switch (s[i]) {case '+':result.push(temp1 + temp2);break;case '-':result.push(temp1 - temp2);break;case '*':result.push(temp1 * temp2);break;case '/':result.push(temp1 / temp2);break;default:break;}}}return result.top();}


这两个是套装,故奉上main()函数,可以一试~:

//6*((5+(2+3)*8)+3)int main(){string s, result;char c;while (cin >> c)s.push_back(c);result = infixTOpostfix(s);cout << result << " = " << postfixCompute(result);getchar();}



阅读全文
0 0