您的位置:首页 > 其它

SSL_1005 计算器的改良(一元一次方程求解)

2017-12-16 15:16 183 查看
Description

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

  

  4+3x=8

  6a-5+1=2-2a

  -5+12y=0

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

Input

  输入的一元一次方程。

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

Output

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

Sample Input


  6a-5+1=2-2a


Sample Output
      a=0.750

思路(总感觉用洛谷写题解好些。。。)

未知数的值=常数和/系数和

不过有很多细节需要注意。

解释在代码:
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
char wzs;//未知数
int i,jsg,zs,xs,m;//zs:常数和,xs:系数和,m:符号开始的位置,用于求系数,jsg:判断是否出现过符号
short b=1;//等号左边还是右边
bool ok[256];//判断当前位数是否是未知数
double ans=0;char c[256];
void qxs(int n)//这个是求上一个符号到当前未知数之间的数,也就是这个未知数的系数
{
bool jg=1;//这里特判,如果等号右边没有任何符号,那么需要把未知数加进去
int k=0;
for (int j=m;j<n;j++)//m是符号的开始位置
if (c[j]>='0'&&c[j]<='9')
k=k*10+c[j]-48;//求之间的系数
for (int j=m;j<n;j++)
{
if (c[j]=='+'||jsg==0) {xs+=k*b;jsg=1;jg=false;break;}//如果是+,把系数加进去
if (c[j]=='-') {xs-=k*b;jg=false;break;}//是-就减
}
if (jg)
xs+=k*b;//特判
}
void js()
{
for (i=0;i<strlen(c);i++)
{
if (c[i]=='+'||c[i]=='-') {m=i;jsg=1;}//存好符号的开始位置,并标记已出现符号
if (c[i]=='=') {b=-1;m=i;continue;}//如果在等号右边,需要变号
if (c[i]==wzs)        //如果这个是未知数
{
ok[i]=1;
if (c[i-1]=='-')//这里解释一下,因为如果前面直接是加号或减号,它的系数就是1或-1
{xs+=-1*b;continue;}
if (c[i-1]=='+'||c[i-1]=='='||i==0)//这里解释一下,如果它是第一个未知数,且前面不是负号(前面已经排除),它的系数就是一;如果是等于号后面的第一个未知数,它的系数也等于1
{xs+=1*b;jsg=1;continue;}
qxs(i);//如果系数不是1或-1
}
}
}
void qzs()//求常数(拼音打错了,见谅。。。)
{
int k=0,fh=1,dh=1;//k是当前的数,fh表示符号,dh表示是等号右边还是左边
for (int i=0;i<strlen(c);i++)
{
if (ok[i]) {k=0;continue;}//如果它是未知数的系数,那么将k清0并跳过
if (c[i]<'0'||c[i]>'9') //如果它不是数,也就是是+,-或=号
{
zs+=k*fh*dh;//将它加到常数里面,如果符号是负号就对应乘过去,如果在等号右边符号又是相反的
k=0;//清0
if (c[i]=='-') fh=-1;//改变符号
if (c[i]=='+') fh=1; //同理
if (c[i]=='=') {dh=-1;fh=1;}//如果在等号右边,所有的符号都会颠倒;fh重新变成+
}
else k=k*10+c[i]-48;//否则将此数存下来
}
zs+=k*fh*dh;//最后一次特殊处理,因为可能还有
}
int main()
{
gets(c);
for (i=0;i<strlen(c);i++)//求未知数
{
if (c[i]<'a'||c[i]>'z') continue;
break;
}
wzs=c[i];//未知数
js();//求系数
qzs();//求常数
zs*=-1;//这里解释一下:因为我们求出的所有的值都在等号左边,所以需要把其中一项移到右边,根据移项变号的原理,所以要乘-1
ans=(double)zs/xs;ans*=1000;ans=floor(ans+0.5);ans/=1000.0;//四舍五入,C++是直接舍尾,所以我们先乘1000,再加0.5,之后取整,最后在除以1000就可以达到保留三位整数的目的了
printf("%c=%0.3lf",wzs,ans);//输出
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: