题目链接:https://leetcode-cn.com/problems/solve-the-equation/description/
求解一个给定的方程,将x
以字符串"x=#value"的形式返回。该方程仅包含'+',' - '操作,变量 x
和其对应系数。
如果方程没有解,请返回“No solution”。
如果方程有无限解,则返回“Infinite solutions”。
如果方程中只有一个解,要保证返回值 x
是一个整数。
示例 1:
输入: "x+5-3+x=6+x-2"
输出: "x=2"
示例 2:
输入: "x=x"
输出: "Infinite solutions"
示例 3:
输入: "2x=x"
输出: "x=0"
示例 4:
输入: "2x+3x-6x=x+2"
输出: "x=-1"
示例 5:
输入: "x=x+2"
输出: "No solution"
直接利用数学解方程式的方法即可,将x的系数全部放到等式的左边,常数全部放到等式的右边,之后相除就可以得到答案了。这里主要是写一个模拟就可以了,特别注意几个特殊的点:
1.等式左边系数为0、右边常数为0时,有无穷解;
2.等式左边系数为0、右边常数不为0时,无解;
3.左右两边相除得到的答案不为整数,按题意要求也属于无解;
4.案例中会出现"0x=0"这种骚操作。
PS:按照题目给定的函数,结果时返回类型为char*的值即字符串的数组名。可是返回结果一直时null,于是我把输出的数组定义到函数之外,做全局变量。这样就过了,原理不是很懂,希望有大佬赐教!
代码如下(有点丑,见谅):
char ans[100];
char* solveEquation(char* equation) {
int x=0,c=0,temp=0,xsign=1,csign=-1,addsign=1;//x为系数,c为常数,temp为字符转存的数,xsign、csign为x和c在等式左右两边的标志,addsign为系数常数前面的正负号标志
int len=strlen(equation);
for(int i=0;i<len;i++){
if(equation[i]=='+'||equation[i]=='-'||equation[i]=='='){
c+=temp*csign*addsign;
temp=0;
if(equation[i]=='='){//到了等式右边,x与c的标志换成相反数,addsign重新初始化为1
xsign*=-1;
csign*=-1;
addsign=1;
}
else if(equation[i]=='+'){
addsign=1;
}
else{
addsign=-1;
}
}
else if(equation[i]!='x'){//字符数转换为整型数
temp=temp*10+equation[i]-'0';
}
else{
if(!temp&&equation[i-1]!='0'){//特殊情况4
temp=1;
}
x+=temp*xsign*addsign;
temp=0;
}
//printf("x=%d c=%d\n",x,c);
}
c+=temp*csign*addsign;//等式末尾需要特殊处理
//printf("x=%d c=%d\n",x,c);
if(!x){
if(!c){
strcpy(ans,"Infinite solutions");//特殊情况1
}
else{
strcpy(ans,"No solution");//特殊情况2
}
}
else{
double solve=1.0*c/x;
int i=2,j=0,answer=(int)solve;
char s[100];
if(solve==answer){
ans[0]='x',ans[1]='=';
if(answer<0){//判断答案的正负
ans[i++]='-';
answer*=-1;
}
do{
s[j++]=answer%10+'0';
answer/=10;
}while(answer);//将答案转化为字符串
s[j]='\0';
while(j){
ans[i++]=s[--j];//将最终结果存入ans数组
}
ans[i]='\0';
}
else{
strcpy(ans,"No solution");//特殊情况3
}
}
return ans;
}