逆波兰式的转换因为题目中浮点数及其带符号的操作数的输入,使得自己忙活以阵子,然后发现只用一个栈来存储操作符号的时候,重新改算法,然后又在输出时必须间隔一个空格处卡住,于是一怒之下不写这道题目,转而攻中缀表达式,结果页是在接受字符串的时候耽搁了半天,终于写出了AC的程序,不过。。各人感觉对给出用例的最后一个有点奇怪,因为明显用本程序是error ,但是没有去特殊判断,然后就AC了,表示奇怪。
#include<iostream>
#include<stack>
#include<string>
#include<iomanip>
#include<vector>
using namespace std;
stack<char> operStack;
stack<float> dataStack;
map<char,int> priority;
char dataSource[35];
//中缀表达式 要从后往前来搞
float operation(float opA,float opB,char opera)
{
switch (opera)
{
case '+':
return opA + opB;
case '-':
return opA -opB;
case '*':
return opA * opB;
case '/':
if(opB == 0.0f)
{
cout<<"ERROR";
exit(0);
}
else
return opA / opB;
default:
cout<<"the wrong operator!"<<endl;
exit(0);
}
}
int main()
{
char *t,*p;
/*operStack.push('#');*/
//其实不用优先级的
vector<char *> value;
// 这里接受字符数组,在用字符串还是字符的问题上纠结了一番
cin.get(dataSource,31);
//strtok 的用法,参数必须是字符数组,NND,后来又查到此函数线程不安全,下面附上strtok_r()的用法
p = strtok(dataSource," ");
value.push_back(p);
while(p)
{
p = strtok(NULL," ");
value.push_back(p);
}
vector<char *>::reverse_iterator iter = value.rbegin();
iter ++;//这里很重要,最后一个是空的,因为字符数组和字符串一样,最后有一个\0表示符
for(;iter != value.rend();iter++)
{
if((*iter)[0] >= '0' && (*iter)[0] <= '9' || (*iter)[1]!='\0')
{
float data = 0.0f;
data = atof(*iter);
dataStack.push(data);
}
else
{
if(dataStack.size() >= 2)
{
float dataA = dataStack.top();
dataStack.pop();
float dataB = dataStack.top();
dataStack.pop();
float midResult = operation(dataA,dataB,(*iter)[0]);
dataStack.push(midResult);
}
else
{
cout<<"ERROR";
exit(0);
}
}
}
cout<< setiosflags(ios::fixed) << setprecision(1)<<dataStack.top()<<endl;
dataStack.pop();
if(!dataStack.empty())
{
cout<<"ERROR";
exit(0);
}
return 0;
}
strtok_c()
void split(const char * str,const char * deli, vector<string> *list) { char buff[1024]; snprintf(buff,sizeof(buff),str); char * gg; char *p = strtok_r(buff, deli, &gg); list->clear(); while(p !=NULL) { list->push_back(p); p = strtok_r(NULL, deli, &gg); }; }
如果确定被切分的字符串不是很长,可以适当减小buff的大小,这样应该可以提高一些效率~
这个封装的函数可以实现将一个字符串切分,并且不改变之前的字符串,切分后的字符串通过用户传入的vector<string>参数获得,这个函数木有内存泄露的问题,也是线程安全的,放心使用吧。