又长知识了,哈哈!
通过这道题让我接触到了一个新的知识点stringstream的用法,同时通过goto语句还可以实现随时跳出循环,也避免了用flag进行标记,本题我也采用容器来存数值和操作符,当然也可以用比较常规的方法。
可以先去了解哦!
string和stringstream用法
描述
郑薇的专业是土木工程,理工科的女生原本就是珍稀动物,而且大多数都长得比较抽象。想她郑微虽然不是什么绝代美女,跟她漂亮的妈妈相比也有一定差距,但她有一张讨喜的圆脸,小巧的尖下巴,大而灵动的眼睛,秀气挺直的鼻子,尤其是皮肤白皙无瑕——这是妈妈也承认自己年轻的时候也比不上的。因此,根据郑微自己无数次揽镜自照的鉴定结果,她绝对称得上是人见人爱、花见花开的美少女,简直就是琼瑶阿姨笔下的女主角。虽然琼瑶阿姨的小说已经落伍几个世纪了,但阿姨的审美观还是历久弥新的,看她挑中的连续剧女主角一个比一个红就知道了。就连一向很少夸人的林静也曾说过郑微不说话的时候还是相当有迷惑性的,称得上“静若处子”。当然,郑微很自觉地过滤掉了他后半句“动若疯兔”的评价,完全当做他对她的肯定。如今想起林静,她的脸上只是微微一笑。
生性豁达的郑薇,埋藏起自己的爱情,开始过上大学时代的忙碌生活。
土木工程的数学题:给定一些没有括号的四则运算表达式,求其结果。
输入
输入数据中含有一些表达式(数量≤1000,长度按含有的运算计,运算符≤30),表达式的运算符只含有加、减、乘、除。表达式中每个数的精度范围在double型内,表达式中没有任何其他运算符,没有括号。
输出
对每个表达式,计算其结果。按科学计数法输出,精度按6位小数,每个结果应占独立一行。如果表达式发生除0的情况,则对该表达式直接输出“DivByZero”。
输入样例 1
3+5.0
6-2*7
6-2/0
3+5*6+1
3+5+1*7
1+2-3*4+5/6-4*3*2*1*1+2+3+4+5
输出样例 1
8.000000e+00
-8.000000e+00
DivByZero
3.400000e+01
1.500000e+01
-1.816667e+01
提示
输出结果请使用printf("%e\n",ans);或者cout<<scientific<<ans<<endl;
下面给出AC代码具体实现:
#include <bits/stdc++.h>
using namespace std;
vector<double> a; //定义数值容器
vector<char> op; //定义操作符容器
int main()
{
int i;
string s;
double number; //数值
char c; //操作符
while (cin >> s)
{
a.clear();
op.clear(); //先将两个容器清空
stringstream st(s); //调用stringstream的构造函数
st >> number; //将st中的字符读入数值中,即将字符型转换成数值型
a.push_back(number); //开始时数值容器为空,此时读进来一个数值
double k = ;
while (st >> c >> number) //st相当与输入流中的cin,再依此将操作符和数值读入
{
if (c == '*')
a.back() *= number; //如果是*则返回两个数值的乘积
else
{
if (c == '/') //若为除号
{
if (number == 0) //倘若此时分母为0
{
printf("DivByZero\n"); //输出此语句
goto out; //直接跳出循环,跳转到out语句,也不执行下面的加法和减法运算
}
else
a.back() /= number;//倘若分母不为0.返回除之后的结果
}
else //倘若既不是*也不是/运算符,则暂时不进行运算,再次输入操作符和数值
{
op.push_back(c);
a.push_back(number);
}
}
}
k = a[0]; //初始值为输入的第一个数值
for (i = 0; i<op.size(); i++) //对剩下的加法和减法进行运算
{
if (op[i] == '+')
k += a[i + 1];//算加减运算
else
k -= a[i + 1];
}
printf("%e\n", k); //最后按科学计数法输出
out: //goto跳转语句,直接跳出,不再执行任何操作
;
}
return 0;
}
也可以用下面的常规方法:
#include <bits/stdc++.h>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
string s1;//输入的一串算式
char op;// +-*/操作符
double num;//算式中的数字
double a[200];//先把*/进行计算后的值
int main()
{
while(cin>>s1)
{
mem(a); //将数组初始化
int t = 0,flag = 0;
double sum = 0;
stringstream s;
s<<s1; //读入一串算式
s>>num; //将字符型转换成数值型
a[0] = num; //第一个读入的数值
while(s>>op>>num) //再依此读入操作符和数值
{
if(op == '+') //先进行*/运算,加减法运算最后执行,将t++统计多少个+-运算符,便于后面进行运算
a[++t] = num;
else if(op == '-')
a[++t] = -num; //若为减法运算符,存入数值的相反数,便于后面直接通过求和进行+-运算
else if(op == '*')
a[t] *= num;
else if(op == '/')
{
if(!num) //如果分母为0,即非真
{
flag = 1; //标记
break; //直径跳出循环不再进行后面的操作
}
a[t] /=num; //倘若分母不为0,则进行除法运算
}
}
if(flag)
printf("DivByZero\n");
else
{
for(int i = 0; i <= t; i++)
sum+=a[i]; //进行+-运算求总和
printf("%e\n",sum); //按科学计数法输出
}
}
return 0;
}
上面的常规方法再稍微改动一点如下:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s;
while(cin>>s)
{
double num[55];
char op[50];
stringstream st(s);
double n;
char c;
int k = 0,j = 0,flag = 1;
st>>n;
num[k++] = n;
while(st>>c>>n)
{
if(c == '*'|| c == '/')
{
if(c == '*')
num[k-1] *= n;
else
{
if(n == 0)
{
flag = 0;
break;
}
num[k-1] /= n;
}
}
else
{
op[j++] = c;
num[k++] = n;
}
}
if(flag)
{
double ans = num[0];
for(int i = 0; i < j; i++)
op[i] == '+' ? ans += num[i+1] : ans -= num[i+1];
cout<<scientific<<ans<<endl;
}
else
cout<<"DivByZero"<<endl;
}
return 0;
}
以上几种写法都可以通过,自行选择其一理解均可;希望我的文章可以帮助你哦!如果有错误的地方还望批评指正,谢谢!