计算器的改良

题目背景

NCLNCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。

题目描述

为了很好的完成这个任务, ZL 先生首先研究了一些一元一次方程的实例:

4+3x=8

6a-5+1=2-26a5+1=22a

-5+12y=0

ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。

你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。

输入输出格式

输入格式:

 

一个一元一次方程。

 

输出格式:

 

解方程的结果(精确至小数点后三位)。

 

输入输出样例

输入样例#1: 
6a-5+1=2-2a
输出样例#1: 
a=0.750
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 //我们规定等式左边opp=1,且将变量放在左边
 4 //我们执行加减都是在遇到符号之后再将之前的做加减 
 5 int sign=1,opp=1,cur,coe;//分别表示符号,在等式的某边 ,当前读入的数值以及系数 
 6 char x;//储存未知数 
 7 double ans;
 8 int main(){
 9     string s;cin>>s;int len=s.length(),value=0,i=0;//value表示常量的值 
10     while(i<=len){
11         if(s[i]>='0'&&s[i]<='9'){
12             cur=cur*10+s[i]-'0';//保存当前值 
13         }
14         else if(s[i]>='a'&&s[i]<='z'){
15             x=s[i];
16             if(cur==0)    coe+=opp*sign;//这里注意要对cur=0也就是系数为一的情况进行特判 
17             else coe+=opp*sign*cur;
18             cur=0,sign=1;//coe的最终值就是等式左边变量的系数了 ,记得将当前值和符号归位 
19         }
20         else if(s[i]=='-'){
21             value+=-opp*sign*cur;//检验到负号有两种情况,一个是系数为-1,一个为减号,不管哪种情况,遇到负号都可以将
22             //当前的值加入到常量value里(),opp前面的负是因为我们要将其移到式子右边
23             sign=-1,cur=0;//将符号改为负且清空当前值 
24         }
25         else if(s[i]=='+'){
26         value+=-opp*sign*cur,sign=1,cur=0;
27         }//遇到正号和负号的情况没什么区别 
28         
29         else if(s[i]=='='){
30             value+=-opp*sign*cur;sign=1,opp=-1;cur=0;//等号也和加减区别不大 PS:记得将符号也初始化为1 
31         }
32         else {value+=-opp*sign*cur;break;}//最后的值累加上去 
33         i++;
34     }
35     ans=(double)value/(double)coe;//常量值除以系数即为结果
36      printf("%c=%.3lf",x,ans==0?abs(ans):ans);//这涉及一个很坑的地方:C++里0除以一个负数值为-0,专门避免这种情况 
37      /*double下存储的数字会有精度误差,比如0可能被存成0.000000000...01
38       然而如果你乘上或者除以一个负数,可能就变成了-0.000000000...01
39       然后因为浮点数是先判定符号再计算数值,就出现了负0这一情况*/
40     return 0;
41 }

 

posted @ 2018-08-04 11:20  清酒令  阅读(1114)  评论(0编辑  收藏  举报