洛谷P1022 计算器的改良 ---- (C语言 + 详细注释)

//这道题我做了好久,解题思路并不难,只是细节处理有些麻烦(可能是我技艺不精,哈哈哈!!),我的想法是:算出总的系数和总的常数,再相除即可,而判断一个数是常数还是系数的依据是看紧跟数字后面的是不是字母(即未知数)。

我AC的代码如下:

#include<stdio.h>
#include<ctype.h>
int main() {
	char s[30];
	gets(s);              //读入字符串
	int p, d1, d2, i, temp, c, flag, sign;        //flag为1表示已经确定了符号
	p = d1 = d2 = temp = 0;          //temp存储每次得到的数值,d1是系数,d2是常数
	while (s[p] != '=')       //p是‘=’的下标,以此为分界限,把未知数都移到其左边,常数移到右边
		p++;
	sign = 1;                 //sign是每次得到数字的符号,1表示正,-1表示负
	flag = 0; 
	for (i = 0; s[i]; i++) {           //遍历字符串
		if (isdigit(s[i])) {          //如果是数字字符
			if (i > 0 && !flag) {    //如果没判断符号,即得到的是连续数字字符的第一位,判断它前面一位是不是负号
				sign = (s[i - 1] == '-') ? -1 : 1;
				flag = 1;           //确定了符号就把flag标为1
			}
			temp = temp * 10 + s[i] - '0';       //高位乘10加本位把字符串转换成数值
		}
		else {                   //如果不是数字,说明连续的数字字符已经完全转换成了数值,下面进行的是判断其是常数还是系数
			temp *= sign;        //带上符号
			if (islower(s[i])) {        //如果数字后面紧跟的是字母(即未知数),说明是系数
				c = s[i];                //由于输出需要,记录未知数是什么
				if (i <= p) {           //i < p说明系数是在等号左边
					if (temp)           //如果temp不为0,说明未知数前面有系数
						d1 += temp;
					else              //temp为0,说明未知数前面没有“显性系数”(即系数为1,省略不写)
						d1 += sign;      //直接加上符号即可(即+1或者-1)
				}
				else {                    //在等号右边
					if (temp)
						d1 -= temp;         //系数移到左边就减去temp
					else
						d1 -= sign;
				}
			}
			else {                 //不是系数就是常数
				if (i <= p)          //在等号左边时,把temp移到右边就要变号
					d2 -= temp;
				else              //在等号右边
					d2 += temp;
			}
			temp = flag = 0;        //每次数值归位后,temp和flag归零
		}
	}
	if (isdigit(s[i - 1]))         //如果最后一位也是数字字符时,那么最后一次没有归位且时常数,补上就完事了
		d2 += temp * sign;
	printf("%c=%.3f", c, 1.0 * d2 / d1);    //d1和d2是整数,乘以1.0把整数转换成浮点型
	return 0;
}
发布了48 篇原创文章 · 获赞 47 · 访问量 3346

猜你喜欢

转载自blog.csdn.net/qq_45472866/article/details/104099848