NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的ZL先生。
题目描述
为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例:
4+3x=8
6a-5+1=2-2a
-5+12y=0
ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。
你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。
输入输出格式
输入格式:
一个一元一次方程。
输出格式:
解方程的结果(精确至小数点后三位)。
输入输出样例
输入样例#1:
6a-5+1=2-2a
输出样例#1:
a=0.750
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char ch[1005],ans;
int num,sum,k1=1,k2=1,xi;
int main()
{
scanf("%s",ch+1);
for(int i=1;i<=strlen(ch+1);i++)
{
if(ch[i]>='0'&&ch[i]<='9')
num*=10,num+=ch[i]-'0';//这个是什么意思捏?
else
{
if(ch[i]>='a'&&ch[i]<='z')
ans=ch[i],xi+=k1*k2*num;//k1 k2的作用也不理解
else
{
sum+=k1*k2*num;
if(ch[i]=='-')
k1=-1;
else if(ch[i]=='+')
k1=1;
else if(ch[i]=='=')
k2=-1,k1=1;
}
num=0;//?
}
}
sum+=k1*k2*num;//不太明白
printf("%c=%.3f\n",ans,(double)-sum/xi);
return 0;
}
解释见注释
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char ch[1005], ans;
int num, sum, k1 = 1, k2 = 1, xi;
int main()
{
scanf("%s", ch + 1);
for (int i = 1; i <= strlen(ch + 1); i++)
{
if (ch[i] >= '0' && ch[i] <= '9')
num *= 10, num += ch[i] - '0'; // 将数字字符串转化为十进制数,数字字符串可能是字母前的系数,或单纯的数值项
else
{
if (ch[i] >= 'a' && ch[i] <= 'z')
ans = ch[i], xi += k1 * k2 * num; // xi表示合并字母前的系数之和,k1表示系数前的符号(即正数为1,负数为-1),
else // k2表示该项是否需要从右边挪到左边,如果该项在左边其值为1,在右边的话,要挪到左边,所以其值为-1
{
sum += k1 * k2 * num; // 把之前的数累加到sum里,同样k1表示数字前的符号,k2表示该数字是否需要从左边挪到右边,需要挪的话,符号要变一下
if (ch[i] == '-')
k1 = -1;
else if (ch[i] == '+')
k1 = 1;
else if (ch[i] == '=')
k2 = -1, k1 = 1;
}
num = 0; // 字母前的系数,或单纯的数值项已累加到xi,或sum,所以num需要重置0以准备转化下一个系数或数值。
}
}
sum += k1 * k2 * num; // 如果输入的方程最后一项是数字
printf("%c=%.3f\n", ans, (double)-sum / xi);
return 0;
}
你如果理解程序解方程的做法剩下的代码就很好理解了。
程序从左到右读取方程的字符串,把未知数的系数累加到变量 xi,把其余整数累加到sum,把等号右侧的移动到左侧,最终转换成:
xi a+sum=0,那a=-sum/xi
k2=1表示在等号左侧,k2=-1表示在右侧(从=右侧移动到左侧变号),k1=1表示+,k1=-1表示减或负数。
读取到数字字符就减去'0'得到数值,存入num。
继续读下一个,还是数字,那原先的num就要放大10倍再加上新数字,num*=10,num += ch[i] - '0';(num全局变量默认初始是0)
当读取到下一个是未知数a~z,那num就要累加到xi,否则累加到sum,累加前通过乘k1乘k2得出是负还是正