这是在做迅雷笔试遇到的一个问题,其实这个题目当时第一个反应是要用到栈,事实上也确实要用到栈的知识,不过我从来没用过,所以只能放弃。事后发现这种题目可以将中缀表达式转为后缀表达式做。其中表达式转换我参考网上的教程写出以下程序:
#include <iostream> #include<map> #include<algorithm> #include<string> #include<stack> using namespace std; int main() { string strMid = "a+b-a*((c+d)/e-f)+g"; string strBed = ""; stack<char> stk; map<char, int> op; op['('] = 0; op[')'] = 0; op['+'] = 1; op['-'] = 1; op['*'] = 2; op['/'] = 2; string::iterator it = strMid.begin();; while( it != strMid.end() ) { if ( op.count(*it) ) { if ( *it == ')' ) { while( stk.top() != '(' ) { strBed += stk.top(); stk.pop(); } stk.pop(); } else if( (!stk.empty()) && op[*it] <= op[stk.top()] ) { while( (!stk.empty()) && op[*it] <= op[stk.top()]) { strBed += stk.top(); stk.pop(); if( stk.empty() ) break; } stk.push(*it); } else if( stk.empty() || *it == '(' || op[*it] > op[stk.top()] ) { stk.push(*it); } } else { strBed += *it; } it++; if ( it == strMid.end() ) { while (!stk.empty()) { strBed += stk.top(); stk.pop(); } break; } } cout << strBed << endl; return 0; }
一直报错,内存溢出,我查看了一下感觉上代码是一模一样的,为什么会出现这种情况,结果发现三个分支逻辑结构的顺序是不能错的,顺序错了就有致命错误。
思路是:
如果遇到非操作符以及出栈情况,一律直接加入后缀表达式
对于操作符会有以下几种情况:
1.遇到操作符‘)‘,需要循环找到’)‘为止,期间不停的出栈,出栈元素保存到后缀表达式
2.遇到操作符’(‘,或者栈已经为空,或者栈顶元素的优先级小于当前操作符,则直接入栈
3.遇到栈顶元素优先级大于等于当前操作符,则一直出栈到小于或者空栈为止,再入栈
把 2 3 两个判断顺序弄反了,结果很悲催,这样就会出现 当前操作符’(‘,然后不停出栈的操作,最后可能导致程序崩溃。