(NOIP2000普及组)洛谷P1022题:手把手教你用C++实现一元一次方程求解器
一、题目分析
洛谷P1022题目要求我们编写程序解一元一次方程。方程中只包含整数、小写字母和+、-、=这三个符号。方程保证合法且有唯一实数解。我们需要将解精确到小数点后三位输出。
二、解题思路
符号处理:正确处理正负号,以及等号两边符号的变化。
变量识别:识别方程中的未知数字母。
计算解:将所有系数移到等号左边,常数项移到右边,最后用常数项除以系数的负数得到解。
三、完整代码
#include <iostream> #include <string> #include <iomanip> using namespace std; int main() { string equation; cin >> equation; // 读取方程字符串 char variable; // 存储未知数字母 double coefficient = 0; // 系数总和 double constant = 0; // 常数总和 int sign = 1; // 当前符号,1表示正,-1表示负 int side = 1; // 当前所在边,1表示左边,-1表示右边 int num = 0; // 临时存储数字 bool hasNum = false; // 标记是否有数字待处理 for (int i = 0; i < equation.size(); i++) { char c = equation[i]; if (isdigit(c)) { // 如果是数字 num = num * 10 + (c - '0'); hasNum = true; } else if (isalpha(c)) { // 如果是字母(未知数) variable = c; if (!hasNum) num = 1; // 如果没有数字,系数默认为1 coefficient += num * sign * side; num = 0; hasNum = false; } else { // 处理符号或等号 if (hasNum) { // 如果有待处理的数字,它是常数项 constant += num * sign * side; num = 0; hasNum = false; } if (c == '+') { sign = 1; } else if (c == '-') { sign = -1; } else if (c == '=') { side = -1; sign = 1; // 等号后符号重置为正 } } } // 处理方程末尾可能剩下的常数 if (hasNum) { constant += num * sign * side; } // 计算解:x = -常数项/系数项 double solution = -constant / coefficient; // 输出结果,保留三位小数 cout << fixed << setprecision(3) << variable << "=" << solution << endl; return 0; }
四、代码详解
变量初始化:
coefficient
:存储所有含未知数的项的系数总和constant
:存储所有常数项的总和sign
:当前项的符号(1或-1)side
:当前处理的是等号左边(1)还是右边(-1)num
:临时存储正在解析的数字hasNum
:标记是否有数字待处理字符处理逻辑:
遇到数字:累积到
num
中遇到字母:确定是未知数,处理系数
遇到符号:处理待处理的数字,然后更新符号
遇到等号:切换处理边,重置符号
特殊情况处理:
省略的系数1(如"x"实际上是"1x")
负号的处理(既可能是减号也可能是负号)
方程末尾可能剩下的常数项
解的计算:
最终解为
-constant / coefficient
使用
fixed
和setprecision(3)
保证输出三位小数
通过这个例子,我们学习了基本的字符串处理和简单数学运算的实现方法,这是编程中非常基础但重要的技能。
原创内容 转载请注明出处