来源:牛客网-》在线测评-》计算机历年考研复试上机题
参考:https://blog.csdn.net/qq_30339595/article/details/79398506
题目描述
设计一个二次方程计算器
输入描述:
每个案例是关于x的一个二次方程表达式,为了简单,每个系数都是整数形式。
输出描述:
每个案例输出两个实数(由小到大输出,中间由空格隔开),保留两位小数;如果无解,则输出“No Solution”。
参考链接写的代码:
#include <iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
string s;
cin>>s;
int a=0,b=0,c=0;
int flag=1;
int sign=1;
int temp=0;//需要考虑当前的数是正负以及多位数情况
int L=s.length();
for(int i=0; i<L; i++)
{
if(s[i]=='=')
{
flag=-1;
sign=1;
i++;
}
if(s[i]=='+')
{
sign=1;
i++;
}
else if(s[i]=='-')
{
sign=-1;
i++;
}
while(s[i]>='0'&&s[i]<='9'&&i<L) //如果是数字且在长度范围内
{
temp=temp*10+(s[i]-'0');
i++;
}
if(temp!=0||i==L)
{
if(i==L||s[i]!='x') //常数项
{
c+=temp*flag*sign;
i--;
}
else if(i==L-1||s[i+1]!='^') //一次项,s[i]一定是x,因为上边判断过了是常数项。。
{
b+=temp*flag*sign;
}
else
{
a+=temp*flag*sign; //二次项
i+=2;
}
}
else
{
if(i==L-1||s[i+1]!='^')
b+=1*flag*sign;
else
{
a+=1*flag*sign;
i+=2;
}
}
temp=0;
}
int pd=b*b-4*a*c;
if(pd<0)printf("No Solution");
else
{
double delta=sqrt(1.0*pd);
double x1=(-b+delta)/(2*a);
double x2=(-b-delta)/(2*a);
if(x1>x2) swap(x1,x2);
printf("%.2f %.2f",x1,x2);
}
return 0;
}
//关键点就是如何处理字符串。
从左到右扫描,系数可能有负数(需要有一个sign来标记),可能是两位数(用while循环来读取)。
遇到的问题:1.在c中输入字符串,只能通过scanf("%s",ch[i]);ch是一个二维数组,如果放一个string的话,会有段错误。
2.在用c输出两位小数时,double类型应该用scanf("%lf",&f);读入,但输出和float类型是一样的,printf("%f",f);没有%lf,会产生输出错误问题。
3.不要判断相等只写一个=啊,造成了死循环。。
边界情况的处理在if判断里,比较麻烦;
当是常数项时,在字符串中间(当前不是x)或者是最后(i==L);当是指数1时,边界情况是(i==L-1)即还剩一个x,或者是i+1不是^(通过判断常数项已经能够判断当前字符是x了);否则就是指数2项。还要判断系数为1的情况,我是通过temp==0来判断,第一次提交时只通过95%的用例,有一个-10x^2-10x=0,结果出错计算得到的b=-11.这就是因为我的判断条件有问题,所以加上了一个temp==0||L==R,就可以了。3h