2017-06-27 19:19:18

第一步需要将中缀表达式转为后缀表达式。这步的转化可以说是本题的核心。

主要的转化手段是利用栈,有如下几个规则:

  • 数字直接输出
  • "("直接进栈
  • ")"将栈中元素出栈直到遇到"("
  • 其他运算符需要和栈顶元素比较优先级,如果栈顶元素的优先级小于等于待操作的运算符的,则需要出栈并输出。直到栈顶元素的优先级大于待处理元素
  • 最后需要将栈中元素清空,全部输出
int toint(string in)
{
int rst;
stringstream ss;
ss<<in;
ss>>rst;
return rst;
} int priority(char a)
{
switch(a)
{
case '*': return ;
case '/': return ;
case '+': return ;
case '-': return ;
case '(': return ;
case ')': return ;
}
} bool isdig(char a)
{
if(a>=''&&a<='') return true;
else return false;
} //保证每次入栈的符号的优先级都比当前的栈顶元素要高,若此时栈顶的优先级比入栈元素低或者等于的话,则需要出栈
//知道遇到比当前需要入栈元素优先级高的为止
void midtopost(string in,vector<string>& vec)
{
stack<char> s;
string rst="";
int i=;
while(true)
{
if(i>=in.length()) break;
if(isdig(in[i]))
{
string num="";
while(isdig(in[i])) num+=in[i++];
vec.push_back(num);
}
else
{
if(s.empty()) s.push(in[i++]);
else
{
if(in[i]=='(') {s.push(in[i]);}
else if(in[i]==')')
{
while(s.top()!='(')
{
string temp="";
temp+=s.top();
vec.push_back(temp);
s.pop();
}
s.pop();
}
else
{
if(priority(in[i])>priority(s.top())||s.top()=='(') s.push(in[i]);
else
{
//判断是否为空必须写在前面,符合短路原则
while(!s.empty()&&(priority(in[i])<=priority(s.top())))
{
string temp="";
temp+=s.top();
vec.push_back(temp);
s.pop();
}
s.push(in[i]);
}
}
++i;
} }
}
//清空栈
while(!s.empty())
{
string temp="";
temp+=s.top();
vec.push_back(temp);
s.pop();
}
} //后缀表达式的计算,数字进栈,符号将栈顶两个元素出栈,运算后进栈
int calc(vector<string>& vec)
{
stack<int> s;
for(int i=;i<vec.size();++i)
{
if(!vec[i].compare("*"))
{
int x=s.top();
s.pop();
int y=s.top();
s.pop();
s.push(x*y);
}
else if(!vec[i].compare("-"))
{
int x=s.top();
s.pop();
int y=s.top();
s.pop();
s.push(y-x);
}
else if(!vec[i].compare("+"))
{
int x=s.top();
s.pop();
int y=s.top();
s.pop();
s.push(x+y);
}
else if(!vec[i].compare("/"))
{
int x=s.top();
s.pop();
int y=s.top();
s.pop();
s.push(y/x);
}
else
{
s.push(toint(vec[i]));
}
}
return s.top();
} int main()
{
string in="9+(3-1)*3+10/2";
//string s="9 3 1 - 3 * + 10 2 / +";
vector<string> vec;
midtopost(in,vec);
cout<<calc(vec)<<endl;
return ;
}

C++ 利用栈解决运算问题的更多相关文章

  1. 【Java EE 学习 69 上】【struts2】【paramsPrepareParamsStack拦截器栈解决model对象和属性赋值冲突问题】

    昨天有同学问我问题,他告诉我他的Action中的一个属性明明提供了get/set方法,但是在方法中却获取不到表单中传递过来的值.代码如下(简化后的代码) public class UserAction ...

  2. 利用栈实现算术表达式求值(Java语言描述)

    利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...

  3. python 利用栈实现复杂计算器

    #第五周的作业--多功能计算器#1.实现加减乘除及括号的优先级的解析,不能使用eval功能,print(eval(equation))#2.解析复杂的计算,与真实的计算器结果一致#用户输入 1 - 2 ...

  4. 利用闭包解决for循环里onclick事件不能捕捉实时i值问题

    问题描述 我们都知道,如果我们对于一组元素(相同的标签)同时进行onclick事件处理的时候(在需要获取到索引的时候),一般是写一个for循环,但是onclick是一个异步调用的,所以会带来一个问题, ...

  5. 用栈解决Largest Rectangle问题

    一问题描述 Given n non-negative integers representing the histogram's bar height where the width of each ...

  6. [Java]利用栈判断括号是否完整配对

    利用栈实现判断字符串中的括号是否都是配对的. 主要算法是依次读取字符串中的每一个字符,如果是左括号则将左括号压入栈中,如果是右括号则从栈中弹出最上面的字符,若两者不是同种括号或栈内已经没有字符就返回f ...

  7. 利用Readability解决网页正文提取问题

    分享: 利用Readability解决网页正文提取问题   做数据抓取和分析的各位亲们, 有没有遇到下面的难题呢? - 如何从各式各样的网页中提取正文!? 虽然可以用SS为各种网站写脚本做解析, 但是 ...

  8. 利用gulp解决微信浏览器缓存问题

    做了好多项目,这次终于要解决微信浏览器缓存这个令人头疼的问题了.每次上传新的文件,在微信浏览器中访问时,总要先清除微信的缓存,实在麻烦,在网上搜罗了很多解决办法,终于找到了方法:利用gulp解决缓存问 ...

  9. hdu 3666(差分约束,手动栈解决超时问题)

    THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

随机推荐

  1. sql中字符串如何比大小

    从字符串的第一个字符开始比较ASSCII码值,如果相等则看下一个,以此类推. 数字的ASCII码<大写字母的ASCII码<小写字母的ASCII码. ASCII码

  2. STA分析(三) cmos模型

    CMOS集成电路的基本结构是以P型材料作为衬底(p-substrate),直接生成NMOS, 同时增加N肼(n-well),在其上制造PMOS. 增加两个bulk(P+,N+)防止非MOS管内的PN结 ...

  3. $.ajax({ }) 里面的success函数不执行 | 回调函数返回的值 用对象,下标,键值对访问不到时

    原因一般是  dataType:'json' 数据类型设置成了json  ,去掉这个设置即可 $.ajax({ }) 回调函数返回的值 用对象,下标,键值对访问不到时,考虑是否返回数据为字符串 考虑是 ...

  4. schema与catalog的理解

    sql环境中Catalog和Schema都属于抽象概念,主要用来解决命名冲突问题.一个数据库系统包含多个Catalog,每个Catalog包含多个Schema,每个Schema包含多个数据库对象(表. ...

  5. xml声明中的standalone属性

    晚上,在测试tinyxml的时候,发现其中声明了<?xml version="1.0" standalone="no" ?>,经查,其含义为stan ...

  6. Win10 Ubuntu 双系统 卸载 Ubuntu

    Win10 Ubuntu 双系统 卸载 Ubuntu 其实卸载 Ubuntu 系统很简单,进 win10 系统之后,磁盘管理,格式化 Ubuntu 的磁盘就可以了. 但是最费劲的是什么呢? 就是格式化 ...

  7. 20145314郑凯杰《网络对抗技术》恶意DLL注入进程(进程捆绑)的实现

    20145314郑凯杰<网络对抗技术>恶意DLL注入进程(进程捆绑)的实现 一.本节摘要 简介:在这部分里,要实现将恶意后门悄无声息地与进程进行捆绑,通过和已运行的进程进行捆绑,达到附着攻 ...

  8. Bof基础实践

    Bof基础 Bof原理 Linux下进程地址空间的布局 典型的堆栈结构 上图中可以看到栈中有return address还有局部变量,也就是函数的参数,bof攻击是利用上参数的溢出将返回地址retur ...

  9. AS不能在手机上现在调试软件

    这两天遇到的一个问题,(android studio2.0以上的版本),在在线调试应用的时候,将手机上的此程序卸载了,然后准备重新再AS中将这个程序推送到手机上,可是这时候发现不能推送,Log显示什么 ...

  10. Eclipse给方法或者类添加自动注释

    自动生成注释: 在团队开发中,注释是必不可少的,为了是自己的注释看起来更加优雅,注释的格式应该统一,我们可以使用Eclipse注释模板自动生成注释. 具体操作如下: 打开注释模板编辑窗口:Window ...