携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
题目描述
给定方程的字符串s,该方程只有加减运算,且是一个一元一次方程。求该方程的解,若方程无解,返回“No solution”,如果方程有无穷多的解,返回“Infinite solutions”。
例1:输入:s="-x+7+3x=-8+x-2" 输出:"x=-17"
解释:通过计算可知x的解为-17。
例2:输入:s="x+7=x+7" 输出:"Infinite solutions"
解释:该方程的解有无穷多个,所以应该返回"Infinite solutions"。
本题值得注意的地方:
- 常量的字符串表示时不会有前导5。
- 方程中x的系数可能为0,表示为0x的形式。
原题地址:640. 求解方程
解题思路
该题的思路很容易想到算出所有常量的值ll,算出所有未知数的系数lx,经过判断常量的值ll和未知数的系数的值lx可以判断解的情况:
- lx==0时
- 若ll==0,则此时方程形式为0x=0,可以看出方程有无穷多解。
- 若ll!=0,此时可知方程形式为0x=3,可知此种情况下方程无解。
- lx!=0时,方程为有解情况,方程的解为(-ll/lx)。
在求解常量ll时,当处理等号左边部分的时候,判断常量字符串前面的+或-号可直接与之前计算的常量直接进行相加。但当处理等号右边的时候,要用之前计算的常量减去当前计算的常量才能得到正确的结果。处理未知数系数时也是如此。
这里要注意当未知数系数为1时会被省略,所以在判断x的系数时,可通过判断x的前一个字符来判断x的系数是否为1。
代码实现
class Solution {
public:
string solveEquation(string s) {
// 分别记录常量的和以及x的系数的和
int ll = 0,lx = 0;
// ispos记录当前数的正负,flag记录当前是在计算等号左边的部分还是等号右边的部分
bool ispos = true,flag = false;
// 依次处理方程字符串
for(int i = 0;i < s.size();){
// 当处理到等号时,记录下来
if(s[i]=='=') i++,flag = true;
// 等号左边的部分正常计算
if(!flag){
if(isdigit(s[i]) || s[i]=='x') ispos = true;
else ispos=s[i] == '+'?true:false,i++;
}
// 等号右边的部分将正负号进行逆向相加
else{
if(isdigit(s[i]) || s[i]=='x') ispos = false;
else ispos=s[i] == '+'?false:true,i++;
}
// 存储常量、系数的值
int num = 0;
// 计算数值
while(i<s.size() && isdigit(s[i])) num = num*10 + (s[i++]-'0');
// 当当前处理的是x的系数时
if(s[i]=='x'){
if(ispos) lx += (i==0 || !isdigit(s[i-1]))?1:num;
else lx -= (!isdigit(s[i-1]))?1:num;
i++;
}
// 当当前处理的是常量时
else{
if(ispos) ll += num;
else ll -= num;
}
}
// 通过判断ll、lx的情况来判断方程解的情况
if(lx == 0){
if(ll == 0) return "Infinite solutions";
else return "No solution";
}else return "x="+to_string(-ll/lx);
}
};