题解 P1022 [计算器的改良]
这道题坑点很多。这里提供一个较为巧妙的做法。
我们其实不用人工移项、合并等操作。
思路:将所有项移到等号左边,最后答案为常数项系数与一次项系数的商的相反数。(很好理解)
用sign代表等号左边或右边,fh表示符号。当搜到未知数(设为x)时,一次项系数 + (当前系数)num * sign * fh;当搜到+ - =时,更新常数项系数。具体见代码。
#include <cstdio>
#include <cstdlib>
#include <cstring>
char c; //读取当前字符
int sign = 1; //sign,表示等号左边(1)与右边(-1)
int num = 0; //当前数
int xnum = 0; //一次项系数
int onum = 0; //常数项系数
char zm = 'x'; //未知数
int fh = 1; //符号
int main()
{
while (1)
{
c = getchar(); //读取一个字符
if (c == '\r') //如果是回车就结束。注意windows里是\n,Linux里是\r
{ //更新当前常数项系数
onum += num * sign * fh;
break;
}
else if (c == '=') //等号,更改sign,更新常数项系数
{
sign = -1;
onum += num * fh;
num = 0;
fh = 1; //默认符号是正
}
else if (c == '-') //减号,同上
{
onum += num * sign * fh;
num = 0;
fh = -1;
}
else if (c == '+') //加号,同上
{
onum += num * sign * fh;
num = 0;
fh = 1;
} //数字符号,更新num
else if (c >= '0' && c <= '9')
{
c -= '0';
num = num * 10 + c;
}
else //更新未知数
{
zm = c;
if (num == 0) //接地气地符合数学表示习惯
xnum += fh * sign;
else
xnum += num * sign * fh;
num = 0; fh = 0;
}
}
//计算答案
double x = - (double (onum) / double (xnum));
if (x == 0) x = 0; //C++尿性
printf ("%c=%.3lf\n", zm, x);
}