问题描述 将多个多项式输入并存储在内存中,然后对多项式进行加,减,数乘,求导等运算。
#include
#include
#define MAX 50 //多项式最多个数
using namespace std;
int n;//当前内存中多项式个数
int t[MAX];//当前多项式求导的次数
//---单链表结点定义-----
struct structnode
{ float coef; //系数
int exp; //指数
structnode *next; //指向下个结点的指针
}*N,*T;//T为每次新建的结点
//----------------------
//---单链表头结点定义-----
struct headnode
{string symbol; //多项式名
structnode *next; //指向下个结点的指针
}head[MAX];
//----------------------
int main()
{//--------函数声明------------
void Input();//输入多项式
void Compute();//计算多项式
void Display();//显示多项式
void Diff();//多项式求导
//----------------------------
char choice;
int i;
for(i=0;i
for(i=0;i
while(choice!='Q'||choice!='q')
{
cout<
<<" I----输入多项式 /n"
<<" C----多项式计算 /n"
<<" L----显示多项式 /n"
<<" F----多项式求导 /n"
<<" Q----退出 /n"
<<"______________________/n"
<<" 输入您的选择:";
cin>>choice;
switch(choice)
{
case 'I': Input(); break;
case 'i': Input(); break;
case 'C': Compute(); break;
case 'c': Compute(); break;
case 'L': Display(); break;
case 'l': Display(); break;
case 'F': Diff(); break;
case 'f': Diff(); break;
case 'Q': return 0;
case 'q': return 0; //选择的字母大小写兼容
default: cout<
}
return 0;
}
void Input()//输入多项式
{int i,j=0,k=0,m;//m记录多项式个数
char a,c;
structnode *L,*P;;
cout<<"请输入多项式的个数:";
cin>>m;
while(m<1||m>MAX)
{cout<<"请输入合适的数字:";
cin>>m;} //暂缺若输入字母时的出错处理
cout<<"输入范例:f= 1,2 2,3 0,-1/n";
cout<<"请输入各多项式名及其系数和指数:/n";
for(j=n;j
cin>>head[j].symbol;//例如读取“f=”
//-------防止重名------------------------
for(i=0;i
{k=1;head[j].symbol="0";}
if(k)
{cout<<"多项式名已存在,请重新输入!/n";
k=0;return;}
//---------------------------------------
i=0;
while(head[j].symbol[i]!='=')i++;
head[j].symbol[i]='/0';//存为“f”
N=(structnode *)malloc(sizeof(structnode));
head[j].next=N;
while ((c=getchar())!='/n')
{cin>>N->coef>>a>>N->exp;
N->next=(structnode *)malloc(sizeof(structnode));
P=N;
N=N->next;}
P->next=NULL;
//让用户以升幂顺序输入多项式
if(head[j].next!=NULL)
{N=head[j].next;
L=N->next;
while(L->exp!=-1)
{if(L->exp
{cout<<"请多项式"< else N=N->next;L=N->next;
}
}
}
n+=m;
}
void Compute()//计算多项式
{char a,b,h,t,s,choice='Y';
int i,f=-1,g=-1;
bool k=0;
structnode *M,*N,*P;
//M指向f的首项/N指向g的首项/P指向h的首项
while(choice=='Y'||choice=='y')
{cout<<"输入算式:";
cin>>h>>a>>t>>b>>s; //b储存运算符
//-------防止重名------------------------
for(i=0;i
k=1;
if(k)
{cout<<"多项式名已存在,请重新输入!/n";
k=0;continue;}
//---------------------------------------
head[n].symbol="0";
head[n].symbol[0]=h;//存储h的名称
for(i=0;i
f=i;//在head[].symbol中找到f
if(f==-1){cout<
g=i;//在head[].symbol中找到g
if(g==-1){cout<
if(head[f].next!=NULL && head[g].next!=NULL)
{M=head[f].next;
N=head[g].next;
P=(structnode *)malloc(sizeof(structnode));
head[n].next=P;
P->next=NULL;
if(b=='-'||b=='+')
{
if(b=='+') //加法运算
{
while(M->next!=NULL && N->next!=NULL)
{
T=(structnode *)malloc(sizeof(structnode));
if(M->exp
{
T->exp=M->exp;
T->coef=M->coef;
T->next=NULL;
P->next=T;
M=M->next;
}
else if(M->exp==N->exp)
{
T->exp=M->exp;
T->coef=M->coef+N->coef;
T->next=NULL;
P->next=T;
M=M->next;
N=N->next;
}
else
{
T->exp=N->exp;
T->coef=N->coef;
T->next=NULL;
P->next=T;
N=N->next;
}
P=P->next;
}
if(M->exp==-1&&N->exp!=-1)
P->next=N;
if(N->exp==-1&&M->exp!=-1)
P->next=M;
}
if(b=='-') //减法运算
{
while(M->next!=NULL && N->next!=NULL)
{
T=(structnode *)malloc(sizeof(structnode));
if(M->exp
{
T->exp=M->exp;
T->coef=M->coef;
T->next=NULL;
P->next=T;
M=M->next;
}
else if(M->exp==N->exp)
{
T->exp=M->exp;
T->coef=M->coef-N->coef;
T->next=NULL;
P->next=T;
M=M->next;
N=N->next;
}
else
{
T->exp=N->exp;
T->coef=-N->coef;
T->next=NULL;
P->next=T;
N=N->next;
}
P=P->next;
}
if(M->exp==-1&&N->exp!=-1)
{ while(N->next!=NULL)
{
T=(structnode *)malloc(sizeof(structnode));
T->coef=-N->coef;
T->exp=N->exp;
T->next=NULL;
P->next=T;
N=N->next;
P=P->next;
}
T=(structnode *)malloc(sizeof(structnode));
T->coef=0;
T->exp=-1;
T->next=NULL;
P->next=T;
}
if(N->exp==-1&&M->exp!=-1)
P->next=M;
}
P=head[n].next;
head[n].next=P->next;
free(P);
}
if(b=='*') //乘法运算
{
while(M->next!=NULL)
{
while(N->next!=NULL)
{T=(structnode *)malloc(sizeof(structnode));
T->coef=M->coef*N->coef;
T->exp=M->exp+N->exp;
P->next=T;
N=N->next;
P=P->next;
}
M=M->next;
N=head[g].next;
}
T=(structnode *)malloc(sizeof(structnode));
T->coef=0;
T->exp=-1;
T->next=NULL;
P->next=T;//补上0,-1结点
P=head[n].next;
head[n].next=P->next;
free(P);
//合并同类项
P=head[n].next;N=P;
if(P->next!=NULL)
{
N=P->next;
T=N->next;
while(P->next!=NULL)
{
while(T->next!=NULL)
{
if(P->exp==T->exp)
{
P->coef=P->coef+T->coef;
N->next=T->next;
free(T);
}
N=N->next;
T=N->next;
}
P=P->next;
N=P;
T=N->next;
}
}
}
}
//-----输出计算结果-----------------------
cout< N=head[n].next;
if(N->coef!=0)
cout<
if(N->next!=NULL)
{
N=N->next; //第一项符号不用输
while(N->next!=NULL)
{
if(N->coef>0)
cout<<"+"<
else if(N->coef<0)
cout<
else
{N=N->next;continue;}
N=N->next;
}
if(N->coef>0)
cout<<"+"<
if(N->coef<0)
cout<
}
cout<
n++; //储存的多项式增加了一个
cout<<"是否继续计算(Y/N):";
cin>>choice;
}
}
void Display()//显示内存中的多项式
{int i,j;structnode *N;
cout<
if(head[0].symbol=="0")cout<<" 当前没有多项式";
else
{
for(i=0;i
for(j=0;j if(head[j].symbol[0]==head[i].symbol[0])
{cout<<" D["< if(k==0)
cout<<" "< k=0;
N=head[i].next;
if(N->coef!=0)
if(N->exp!=0)
cout<
else
cout<
if(N->next!=NULL)
{
N=N->next;
while(N->next!=NULL)
{
if(N->coef>0)
cout<<"+"<
else if(N->coef<0)
cout<
else
{N=N->next;continue;}
N=N->next;
}
if(N->coef>0)
cout<<"+"<
else if(N->coef<0)
cout<
else {cout<
}
cout<
}
}
void Diff()//多项式求导
{int i,k=-1;//k储存多项式的位置/m储存已求导过的次数
char h,choice='Y';
structnode *N,*P,*T;
cout<<"/n内存中现有的多项式为:/n";
cout<<"______________________/n";
Display();
cout<<"______________________/n";
while(k==-1)
{
cout<<"请输入要进行求一次导的多项式名:";
cin>>h;
for(i=0;i
k=i;
if(k==-1)
cout<
//在内存中查找是否有所输入的多项式
head[n].symbol=head[k].symbol;
N=head[k].next;
head[n].next=(structnode *)malloc(sizeof(structnode));
P=head[n].next;
while(N->next!=NULL)
{
T=(structnode *)malloc(sizeof(structnode));
T->coef=N->coef;
T->exp=N->exp;
T->next=NULL;
P->next=T;
N=N->next;
P=P->next;
}
P->next=(structnode *)malloc(sizeof(structnode));
P=P->next;
P->coef=0;
P->exp=-1;
P->next=NULL;
P=head[n].next;
head[n].next=P->next;
free(P);
while(choice=='Y'||choice=='y')
{
N=head[n].next;
while(N->next!=NULL)
{
N->coef=N->coef*N->exp;
N->exp--;
N=N->next;
}
//--输出-----
cout<<"D["< N=head[n].next;
P=N->next;
if(P->next==NULL)//只有一个结点的输出
{
if(N->coef==0)
{cout<<"0";return;}
else
if(N->exp>0)
cout<
else if(N->exp==0)
cout<
}
else//多个结点的输出
{
if(N->coef==0||N->exp<0)//销毁系数为0或者指数小于0的结点
{
head[n].next=P;
free(N);
N=P;
}
if(N->next!=NULL)
{if(N->exp>0)
cout<
else
cout<
N=N->next;
while(N->next!=NULL)
{
if(N->coef<0)
cout<
else
cout<<"+"<
N=N->next;
}
}
}
cout<
cin>>choice;
t[n]++;
}
n++;
}
感想
历时一个星期,我终于成功地编完了这个程序!其中酸甜苦辣自不必言,然而令我欣慰的是写算法和调错误的能力的大幅提高。
还没写之前,我就琢磨:一元多项式的主要涉及的数据结构是单链表,对指针的操作是最根本也是最重要的操作。指针用起来效率高,但是产生的错误比较隐蔽,需要有高度的耐性和毅力才能攻克难关。
有了这个思想准备,我就开始比较小心地写程序,每写一个算法之前都先把思路理清,把指针的操作想明白,但这其中还是出现了不小的麻烦。比如多项式的读取问题,若输入f= 1,2 2,3 0,-1 那么读取的时候如何区分类型并且存入相应的位置呢?经过查资料才发现cin在读取的时候是以空格为界逐个进行的,比如cin>>a>>b,其中a是整型,b是字符型,那么输入“12 m”时就把“12”存入a中,把“m”存入b中。有了这个认识,问题就迎刃而解了!还有一个比较棘手的问题就是对指数无序的单链表进行排序,本来想实现指数无序输入再内部进行升幂排序的功能,但考虑之后发现如果超过三个结点需要用四个指针来操作,而且过程极为繁琐,最终没有想出好的算法,只能作罢。所以我的程序要求用户必需按升幂顺序输入,而且不能有同类项,这个问题也作为以后我继续攻克的难点之一。由于内存中的多项式都是升幂的,而我的程序具有多次求导的功能,那么当多项式的第一项多次求导后变为0,而第二项的指数大于0,在输出的时候第二项前面的“+”就不必输出。所以每次进行求导一旦有这种情况都要进行调整,想起来很容易,做起来却很麻烦。经过程序的多次修改,最终花了两个多小时才解决了这个问题,可见编程真是步步为营,一点都马虎不得!从输入的读取到核心的算法一直到输出,都要以认真严谨的态度来对待。
当然程序还有许多值得改进的地方,比如多项式的输入和读取缺乏健壮性,对输错的内容无法进行处理等等。无论如何,能比较圆满地完成这个课题对我来说是个极大的鼓舞,它让我享受到了编程的快乐,同时也留下了我成熟的印痕,成为我漫漫编程路上的一个里程碑。