问题:设计一个能求解二次方程的计算器,要求输入任意形式的二次方程(系数为整数),输出该方程的解,保留小数点后两位。
问题分析:由于输入的值包括x,+,-,^等符号,于是采用字符型数组记录输入的方程式,这样关键问题就是如何将二次项,一次项以及常数项的系数记录下来并转化为整型变量。我认为主要的难点有两点:
(1)将各种输入的各种情况考虑清楚,不能出现遗漏的情况。其中二次项和一次项系数的求法类似,主要考虑系数前的符号,在等式的左右哪边,是否有显式的数字以及系数相乘等情况,对于常数项,对于如何捕捉常数项我分了两种情况,方程末尾的常数项和非末尾的常数项,具体情况见以下代码。
(2)将两位数甚至更高位数的系数转化为整型的二位数甚至更高位数。
程序代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAX 100
int change(char *a) //将字符型系数转化成整型系数
{
int sum=0,i=0;
while(*(a+i)<='9'&&*(a+i)>='0')
{
i++;
}
while(*a<='9'&&*a>='0')
{
sum+=(*a-'0')*pow(10,i-1);
a++;
i--;
}
if(*a=='*')
{
a++;
sum*=change(a);
}
return sum;
}
void main()
{
char A[MAX];
int i,j,a=0,b=0,c=0,signal=1;
gets(A);
for(i=0;A[i]!=' ';i++)
{
if((A[i]=='x')&&(A[i+1]=='^')&&(A[i+2]=='2')) //求二次项系数
{
if(i==0)
a=1;
else if(A[i-1]=='+') //没有显式的数字
a+=signal;
else if(A[i-1]=='-')
a-=signal;
else if(A[i-1]=='*'||(A[i-1]>='0'&&A[i-1]<='9')) //找到系数中第一位数字的位置
{
j=i-1;
while((A[j]>='0'&&A[j]<='9')||A[j]=='*')
{
j--;
}
if(A[j]=='+'||A[j]=='='||j==-1)
a+=change(&A[j+1])*signal;
if(A[j]=='-')
a-=change(&A[j+1])*signal;
}
}
if(A[i]=='x'&&A[i+1]!='^') //求一次项的系数
{
if(i==0)
b=1;
else if(A[i-1]=='+')
b+=signal;
else if(A[i-1]=='-')
b-=signal;
else if(A[i-1]=='*'||(A[i-1]>='0'&&A[i-1]<='9'))
{
j=i-1;
while((A[j]>='0'&&A[j]<='9')||A[j]=='*')
{
j--;
}
if(A[j]=='+'||A[j]=='='||j==-1)
b+=change(&A[j+1])*signal;
if(A[j]=='-')
b-=change(&A[j+1])*signal;
}
}
if((A[i]=='+'||A[i]=='-'||A[i]=='=')&&A[i-1]>='0'&&A[i-1]<='9'&&A[i-2]!='^') //求常数项
{
j=i-1;
while((A[j]>='0'&&A[j]<='9')||A[j]=='*')
{
j--;
}
if(A[j]=='+'||A[j]=='='||j==-1)
c+=change(&A[j+1])*signal;
if(A[j]=='-')
c-=change(&A[j+1])*signal;
}
if(A[i]>='0'&&A[i]<='9'&&A[i+1]==' ') //求方程末尾的常数项
{
j=i;
while((A[j]>='0'&&A[j]<='9')||A[j]=='*')
{
j--;
}
if(A[j]=='+'||A[j]=='='||j==-1)
c+=change(&A[j+1])*signal;
if(A[j]=='-')
c-=change(&A[j+1])*signal;
}
if(A[i]=='=') //判断是在等式哪一边
signal=-1;
}
int Dalte=b*b-4*a*c;
double x1,x2;
if(Dalte>=0)
{
x1=(double)((-1)*b+sqrt(Dalte))/(2*a);
x2=(double)((-1)*b-sqrt(Dalte))/(2*a);
printf("%.2f %.2f
",x1,x2);
}
if(Dalte<0)
printf("No Solution
");
}
程序分析:该程序基本能满足题目的要求,对各种情况的输入都能准确记录各项的系数,并且用到函数的递归调用,来记录系数相乘的情况。但是这段程序的主要问题在于重复的代码太多,我考虑过用函数的调用来缩短程序代码,并使整个程序更加地模块化。但是按照我自己的思路设计出的程序会出现指针越界的情况,这在函数调用时不好解决,于是没有进一步采用函数的调用。另外,这段程序没有进行出错处理,这也是需要进一步改进的地方。我会进一步改进该程序并进一步提高自己的编程能力。