嗨,这道题是个好题,既考了字符串操作函数,又考了栈的使用
遵循一个操作符旁边有两个操作数,用两个栈,一个操作符栈和一个操作数栈,模拟操作的出波兰式
代码要做的是:(利用运算符的优先级)
1、初始化一个操作符栈,一个操作数栈
2、反向开始,因为是求波兰式,如果遇到数字,将数字这段字符串进入操作数栈;如果操作符栈为空,直接将操作符入栈,遇到‘)’,直到遇到‘(’,将操作符栈中的操作符取出,每取出一个操作符,就从操作数栈中取出两个字符串,组合成新的字符串再次入操作数栈,(主要遵循一个操作符左右必有两个操作数或表达式);如果将要进入操作数栈的优先级大于里面的,直接入栈,如果小于栈里的操作符,则取出一个操作符,必取出两个操作数。
3、最后还是利用栈将表达式计算出来
还有一种方法是将表达式还原成二叉树,前序表达式就是所求,接下来写完会更新
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstdlib>
#include<string>
#include<map>
using namespace std;
#define N 105
typedef long long LL;
map<char,int>mp;
map<char,string>mt;
const string sample = "+-*/()";
void Init()
{
mp['+'] = 1;mp['-'] = 1;mp['*'] = 2;
mp['/'] = 2;mp['('] = 0;mp[')'] = 0;
mt['+'] = "+";mt['-'] = "-";
mt['*'] = "*";mt['/'] = "/";
}
stack<string>num; //储存操作数
stack<char>opt; //储存操作符
bool judge(char ch)
{
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
string getstring(string s)
{
while(!num.empty()) num.pop();
while(!opt.empty()) opt.pop();
string newstring;
for(int i = s.size() - 1;i >= 0;--i)
{
if(isdigit(s[i]))
{
int index = s.find_last_of(sample,i);
string numstring = s.substr(index + 1,i - index);
//cout << numstring << endl;
num.push(numstring);
i = index + 1;
}
else{
if(s[i] == ')')
opt.push(s[i]);
else{
if(!opt.empty() && s[i] == '(')
{
while(opt.top() != ')')
{
char ptr = opt.top();
opt.pop();
string x = num.top();num.pop();
string y = num.top();num.pop();
string tmp = mt[ptr] + " " + x + " " + y;
//cout << tmp << endl;
num.push(tmp);
}
opt.pop();
}
else{
if(!opt.empty() && mp[s[i]] >= mp[opt.top()])
opt.push(s[i]);
else{
//cout << s[i] << " " << opt.top() << endl;
if(!opt.empty() && mp[s[i]] < mp[opt.top()])
{
while(!opt.empty() && mp[s[i]] < mp[opt.top()])
{
char ptr = opt.top();
opt.pop();
string x = num.top();num.pop();
string y = num.top();num.pop();
string tmp = mt[ptr] + " " + x + " " + y;
//cout << tmp << endl;
num.push(tmp);
}
opt.push(s[i]);
}
else{
if(opt.empty() && judge(s[i]))
opt.push(s[i]);
}
}
}
}
}
}
while(!opt.empty())
{
char ptr = opt.top();
opt.pop();
string x = num.top();num.pop();
string y = num.top();num.pop();
string tmp = mt[ptr] + " " + x + " " + y;
//cout << tmp << endl;
num.push(tmp);
}
newstring = num.top();
return newstring;
}
LL cal(string s)
{
stack<LL>sta;
for(int i = s.size() - 1;i >= 0;--i)
{
//if()
if(isdigit(s[i]))
{
int index = s.find_last_of(' ',i);
string tmp = s.substr(index + 1,i - index);
LL n;
sscanf(tmp.c_str(),"%lld",&n);
sta.push(n);
i = index + 1;
}
else{
if(s[i] != ' ' && judge(s[i]))
{
LL n = sta.top();sta.pop();
LL m = sta.top();sta.pop();
switch(s[i])
{
case '+':sta.push(n + m);break;
case '-':sta.push(n - m);break;
case '*':sta.push(n * m);break;
case '/':sta.push(n / m);break;
}
}
}
}
return sta.top();
}
int main()
{
/*string s = "456+*-/";
cout << atoi(s.c_str()) << endl;*/
string s;
s = "456";
//初始化操作符的优先级
Init();
int k = 0;
//cout << judge('-') << endl;
while(cin >> s)
{
k++;
printf("Case %d:\n",k);
string tmp = getstring(s);
cout << tmp << endl;
cout << cal(tmp) << endl;
}
return 0;
}
重建二叉树求解:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
#include<cmath>
#include<stack>
using namespace std;
typedef struct Tree{
int num;
struct Tree *leftchild;
struct Tree *rightchild;
}Tree,*Node;
typedef long long LL;
map<int,char>mp;
map<char,LL>mp1;
string sample = "+-*/()";
void Init()
{
mp1['+'] = 101; mp1['*'] = 201;
mp1['-'] = -101; mp1['/'] = -201;
mp1['('] = -1; mp1[')'] = -2;
mp[101] = '+'; mp[201] = '*';
mp[-101] = '-'; mp[-201] = '/';
mp[-1] = '('; mp[-2] = ')';
}
LL a[50];
void solve(string s,int &k)
{
k = 0;
for(int i = 0;i < s.length();++i)
{
if(isdigit(s[i])){
int index = s.find_first_of(sample,i);
string tmp = s.substr(i,index - i);
LL num;
//cout << tmp << endl;
sscanf(tmp.c_str(),"%lld",&num);
//cout << num << endl;
a[k++] = num;
i = index - 1;
}
else{
a[k++] = mp1[s[i]];
//cout << mp1[s[i]] << " " << a[k - 1] << endl;
}
}
/*for(int i = 0;i < k;++i)
{
printf("%lld ",a[i]);
}*/
}
bool check(char ch)
{
if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
return true;
else
return false;
}
Node createTree(LL *res,int start,int end)
{
int test = 0;
//去除空格
bool flag = false;
if(res[start] == mp1['(']){
for(int i = start;i <= end;++i)
{
if(res[i] == mp1['('])
test++;
else{
if(res[i] == mp1[')'])
test--;
else{
if(test == 0 && i != end)
{
flag = true;
break;
}
}
}
}
if(!flag)
{
start++;
end--;
}
}
int num = 0;//num=0说明不在括号里面
if(start == end){
Node node = (Tree *)malloc(sizeof(Tree));
node -> num = res[start];
node -> leftchild = NULL;
node -> rightchild = NULL;
return node;
}
int tmp = 300;//优先级最小的运算符
int ptr;
for(int i = start;i <= end;++i)
{
if(res[i] == mp1['('])
num++;
else{
if(res[i] == mp1[')'])
num--;
else{
if(num == 0)
{
if(abs(res[i]) > 100){
if(abs(res[i]) <= tmp){
tmp = abs(res[i]);
ptr = i;
}
}
}
else
continue;
}
}
}
Node node = (Tree *)malloc(sizeof(Tree));
node -> num = res[ptr];
node -> leftchild = createTree(res,start,ptr - 1);
node -> rightchild = createTree(res,ptr + 1,end);
return node;
}
LL b[50];
int x = 0;
void preorder(Node root)
{
if(root)
{
b[x++] = root -> num;
preorder(root -> leftchild);
preorder(root -> rightchild);
}
}
LL cal()
{
stack<LL>sta;
LL res;
for(int i = x - 1;i >= 0;--i)
{
if(abs(b[i]) > 100)
{
LL c = sta.top();sta.pop();
LL d = sta.top();sta.pop();
switch(mp[b[i]])
{
case '+':res = c + d;break;
case '-':res = c - d;break;
case '*':res = c * d;break;
case '/':res = c / d;break;
}
sta.push(res);
}
else{
sta.push(b[i]);
}
}
return sta.top();
}
int main()
{
string s;
Init();
int k = 0;
while(cin >> s)
{
k++;
int len;
solve(s,len);
/*for(int i = 0;i < len;++i)
{
printf("%lld ",a[i]);
}*/
printf("Case %d:\n",k);
Node root;
root = createTree(a,0,len - 1);
x = 0;
preorder(root);
for(int i = 0;i < x - 1;++i)
{
if(abs(b[i]) >= 100){
cout << mp[b[i]] << " ";
}
else{
cout << b[i] << " ";
}
}
cout << b[x - 1] << endl;
cout << cal() << endl;
}
return 0;
}