标签:blog ar io os sp for on 2014 log
/* 求前缀表达式的值(25)
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式
前缀表达式指二元运算符位于两个运算数之前,
例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4
请设计程序计算前缀表达式的结果值。
输入格式说明:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,
不同对象(运算数、运算符号)之间以空格分隔
输出格式说明:
输出前缀表达式的运算结果,精确到小数点后1位,或错误信息“ERROR”
样例输入与输出:
序号 输入 输出
1 + + 2 * 3 - 7 4 / 8 4 13.0
2 / -25 + * - 2 3 4 / 8 4 12.5
3 / 5 + * - 2 3 4 / 8 2 ERROR
4 +10.23 10.2
分析:
1)将所有元素顺序放入队列,如发现其后跟两个数的符号,
丢弃符号和两数,并将将结果放入符号位置
2)往返进行,直到最后只剩一个元素,输出
3)计算如出现错误,输出ERROR并返回,如结果无误输出时结果保留一位小数
*/
#include<iostream>
#include<string>
#include<sstream>
#include<cstdlib> // gcvt 或 sprintf
#include<iomanip>
using namespace std;
double Calcult(string op, double a, double b)
{
switch(op[0])
{
case '+':return a + b; break;
case '-':return a - b; break;
case '*':return a * b; break;
case '/':return a / b; break;
}
}
void Input(string q[], int& i)
{
string line,str;
getline(cin, line, '\n');
istringstream stream(line);
i = 0;
// 此步已去除正数前的正号
while(stream >> str)
{
q[i++] = str;
}
}
bool IsOper(string& item)
{
return (item == "+" || item == "-" || item == "*" || item == "/") ? true : false;
}
void GetVal(string q[], int len)
{
double a, b;
string op;
char val[20];
while(len > 1)
{
for(int i = 0; i < len; ++i)
{
if( IsOper(q[i]) )
{
if(i + 2 < len && !IsOper(q[i + 1]) && !IsOper(q[i + 2]))
{
op = q[i];
a = strtod(q[i + 1].c_str(), NULL);
b = strtod(q[i + 2].c_str(), NULL);
if(op == "/" && b == 0)
{
cout << "ERROR" << endl;
return;
}
for(int j = i+1; j < len-2; ++j)
q[j] = q[j + 2];
len -= 2;
// Linux 下不能用 sprintf_s, 也不能用 _gcvt_s,
// 而用 gcvt(浮点值, 15, val); 其中 15 是有效位数
// 缓冲区、缓冲区大小(减1位,保存结束符?)、浮点数、有效位数(最大为17)
_gcvt_s(val, 19, Calcult(op, a, b), 17);
q[i] = val;
}
}
}
}
cout << setiosflags(ios::fixed) << setprecision(1) << strtod(q[0].c_str(),NULL) << endl;
}
void Run()
{
string q[30];
int len;
Input(q,len);
GetVal(q,len);
}
int main(void)
{
Run();
return 0;
}标签:blog ar io os sp for on 2014 log
原文地址:http://blog.csdn.net/mywsfxzxb/article/details/41963669