【题目描述】
NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例:
4+3x=8
6a-5+1=2-2a
-5+12Y=0
ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母 及十、一、=这三个数学符号(当然,符号“一”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
【输入】
输入一个一元一次方程,可认为输入的一元一次方程均为合法的,且有唯一实数解。
【输出】
将解方程的结果(精确至小数点后三位)输出。
【输入样例】
6a-5+1=2-2a
【输出样例】
a=0.750
解题思路:将方程化简为ax+b=0的形式,然后求出x = -b/a。 要考虑到一些细节:例如等号右边的项移到左边要变好,变量前面如果没有数字则表示系数为1等。
#include <bits/stdc++.h> using namespace std; int main(){ string s; //将输入的方程式存储在字符串s中 char c,cr; //c:一次取出字符串s中的每个字符存放在c中。 cr:存储用来表示变量的字母,在最后输出结果时使用 double r; //r:存储方程的解 // a为未知数的系数,b为常数项 ,num表示方程中每一项的系数或常数的数值(不含符号)初始设为0, //op:表示 系数或常数的符号( +或者-) dir:等号左边为1,右边为-1 //最终目标是将方程化简为 ax+b=0的形式,则x = b / a; int a=0,b=0,num=0,op=1,dir=1; cin>>s; for(int i=0;i<s.size();i++){ c = s[i];//依次读字符串中的每个字符进行处理 if(isdigit(c)){ num = num*10 + c-'0'; //取出的字符为数字,则对num进行累加 }else if(isalpha(c)){ //取出的值是字母 即为变量 cr = c; if(num==0) { //如果取出变量时,num=0,说明在变量前没有数字,则系数为1,故将num=1; num = 1; } a = a + num * op * dir; //加变量的系数a num=0; }else{ b = b + num*op * dir; //当取出的不是数字也不是字母时,累加常量b if(c=='+'){ op = 1; }else if(c =='-'){ op = -1; }else if(c=='='){ //遇见等号后,dir要变为负值,因为等号右边的项移到左边累加时要变号 dir = -1; op = 1; } num = 0; } } b = b + num*op * dir; //要考虑当等号右边最后一项为数字时,按前面的过程是没有累加上的,故在此考虑 // cout<<a<<" "<<b<<endl; if(b==0){ r=0.000; //当b=0时,有可能会出现r=-0的情况,要考虑到。如测试点:-a+1a-3=a-3 }else{ r = (-1)*b*1.0 / a; } cout<<cr<<"="<<fixed<<setprecision(3)<<r; return 0; }
测试数据:
输入1:
20+3x=-18
输出1:
x=-12.667
输入2:
-6+12x=0
输出2:
x=0.500
输入3:
47-2=6y+3
输出3:
y=7.000
输入4:
-25a+18-2=-7a-2
输出4:
a=1.000
输入5:
-a+1a-3=a-3
输出5:
a=0.000