final vision
这个版本可以针对:
1、对用括号包括进去的负数的运算
2、对于有小数点的数进行运算
3、有小数点的负数进行运算。
这个版本
并没有手动编一个栈,而是用了stl标准库里的栈。
运行范例
input:
-5+(-3+(9-4*3)*2)/3+4
-7+(-5)*3
2.05+9.8/2
-5+(-3.6+(9.98-4*3)*2.6)/3+4
output
1、
eg1、
eg2、
eg3、
eg4、
#include<iostream>
#include<cstring>
#include<vector>
#include<string>
#include<stack>
#include<algorithm>
#define maxn 10050
using namespace std;
stack<double>snum;
stack<char>sf;
vector<double>num;
vector<char>f;
vector<int>knum; //第countk 个括号后的数的个数
int countk; //countk 为括号数
string st;
vector<double>temnum;
string temstf;
int sti;
bool is_f(int i){
if (st[i]=='+'||st[i]=='-'||st[i]=='*'||st[i]=='/')
{
return true;
}
return false;
}
bool is_num(int i){
if (st[i]<='9'&&st[i]>='0')
{
return true;
}
return false;
}
bool is_priority(int i){
if (temstf[i-1]=='*'||temstf[i-1]=='/')
{
return true;
}
else if (temstf[i-1]=='+'||temstf[i-1]=='-')
{
if (temstf[i]=='+'||temstf[i]=='-')
{
return true;
}
}
return false;
}
double calculate(double a,double b,char c){
switch(c){
case '+':return a+b;
case '-':return b-a;
case '*':return a*1.0*b;
case '/':return b*1.0/a;
}
return 0;
}
double compute(){
int numi = 1,fi = 1;
snum.push(temnum[numi-1]);
sf.push(temstf[fi-1]);
snum.push(temnum[numi]);
//放入栈中
while(fi<temstf.length()){ //先能放进栈的都先放进栈 能进来肯定还有数
if (is_priority(fi)) //就是比原来优先级小的情况 => 要先算出来再放
{
double tema = snum.top();
snum.pop();
double temb = snum.top();
snum.pop();
char temch = sf.top();
sf.pop();
snum.push(calculate(tema,temb,temch));
sf.push(temstf[fi]);
fi++;
numi++;
snum.push(temnum[numi]);
}
else { //优先级不够的话 就按顺序push
sf.push(temstf[fi]);
fi++;
numi++;
snum.push(temnum[numi]);
}
}
//栈内部的计算
while(!sf.empty()){ //当非空的时候
double tema = snum.top();
snum.pop();
double temb = snum.top();
snum.pop();
char temch = sf.top();
sf.pop();
snum.push(calculate(tema,temb,temch));
}
double temd = snum.top();
snum.pop();
return temd;
}
int main(int argc, char const *argv[])
{
sti = 0;
cin>>st;
//先遍历一遍把有负数的情况搞成0-一个数
for (int i = 0; i < st.length(); ++i)
{
if (st[i]=='-')
{
if (i==0)
{
st.insert(0,1,'0');
}
else if (st[i-1]=='(')
{
st.insert(i,1,'0');
}
}
}
knum.push_back(0);
for (int i = 0; i < st.length(); ++i)
{
if (is_num(i))
{
string temst;
temst.clear();
temst += st[i];
while(!is_f(i++))
{
temst +=st[i];
}
double temd;
float temf = atof(temst.c_str());
temd= temf;
i-=2;
knum[countk]++; //第countk 括号后边有多少数
num.push_back(temd);
}
if (is_f(i)&&i<st.length())
{
f.push_back(st[i]);
}
if (st[i]=='(')
{
countk++;
knum.push_back(0);
}
if (st[i]==')') //第i个是括号,前面的都是数
{
for (int i = 0; i < knum[countk]; ++i) //将数字的临时字符串解析下来
{
temnum.push_back(num[num.size()-1-i]);
}
reverse(temnum.begin(),temnum.end());
num.erase(num.begin()+num.size()-knum[countk],num.begin()+num.size());
for (int i = 0; i < knum[countk]-1; ++i) //将符号的临时字符串解析下来
{
temstf+=f[f.size()-1-i];
}
reverse(temstf.begin(),temstf.end());
f.erase(f.begin()+f.size()-knum[countk]+1,f.begin()+f.size());
num.push_back(compute());
knum.erase(knum.begin()+countk);
countk--;
knum[countk]++;
//在每次的传入后 让下一次compute前让这个向量和这个string 清空
temnum.clear();
temstf.clear();
}
}
//遍历完了一遍,最后得到了一个无括号的temnum向量和temstf 的string。=>输出compute答案
//记得把num赋给temnum 把f赋给temstf
for (int i = 0; i < num.size(); ++i)
{
temnum.push_back(num[i]);
}
for (int i = 0; i < f.size(); ++i)
{
temstf+=f[i];
}
cout<<compute()<<endl;
return 0;
}
// @Aczy156
// 2019/3/30