数据结构课程设计之二—— 一元多项式

问题描述  将多个多项式输入并存储在内存中,然后对多项式进行加,减,数乘,求导等运算。

#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 head[i].symbol="0";//多项式名初始化
for(i=0;i t[i]=1;//求导次数记录数组初始化


while(choice!='Q'||choice!='q')
 {
  cout<  <<"______________________/n"
  <<"  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  if(head[i].symbol[0]==head[j].symbol[0])
  {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->expexp || L->exp==N->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  if(head[i].symbol[0]==h)
   k=1;
 if(k)
  {cout<<"多项式名已存在,请重新输入!/n";
  k=0;continue;}
 //---------------------------------------

 head[n].symbol="0";
 head[n].symbol[0]=h;//存储h的名称
 for(i=0;i  if(head[i].symbol[0]==t)                //未完善
   f=i;//在head[].symbol中找到f
 if(f==-1){cout< for(i=0;i  if(head[i].symbol[0]==s)                //未完善
   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->expexp)
    {
     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->expexp)
     {
      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<coef<<"x^"<exp;
  if(N->next!=NULL)
  {
   N=N->next; //第一项符号不用输
    while(N->next!=NULL)
    {
     if(N->coef>0)
      cout<<"+"<coef<<"x^"<exp;
     else if(N->coef<0)
      cout<coef<<"x^"<exp;
     else
     {N=N->next;continue;}
     N=N->next;
    } 
   if(N->coef>0)
    cout<<"+"<coef<<"x^"<exp;
   if(N->coef<0)
    cout<coef<<"x^"<exp;
  }
  cout<  //-----------------------------------------

 n++; //储存的多项式增加了一个
 cout<<"是否继续计算(Y/N):";
 cin>>choice;
}
}

void Display()//显示内存中的多项式
{int i,j;structnode *N;
cout<bool k=0;

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<coef<<"x^"<exp;
   else
    cout<coef;
  if(N->next!=NULL)
  {
   N=N->next;
   while(N->next!=NULL)
    {
     if(N->coef>0)
      cout<<"+"<coef<<"x^"<exp;
     else if(N->coef<0)
      cout<coef<<"x^"<exp;
     else
     {N=N->next;continue;}
     N=N->next;
    } 
   if(N->coef>0)
     cout<<"+"<coef<<"x^"<exp;
   else if(N->coef<0)
     cout<coef<<"x^"<exp;
   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   if(head[i].symbol[0]==h)
    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<coef<<"x^"<exp;
   else if(N->exp==0)
    cout<coef;
 }
 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<coef<<"x^"<exp;
  else
   cout<coef;
  N=N->next;
   while(N->next!=NULL)
   {
    if(N->coef<0)
     cout<coef<<"x^"<exp;
    else
     cout<<"+"<coef<<"x^"<exp;
    N=N->next;
   }
  }
 }

 cout< cout<<"是否继续求导(Y/N):";
 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,在输出的时候第二项前面的“+”就不必输出。所以每次进行求导一旦有这种情况都要进行调整,想起来很容易,做起来却很麻烦。经过程序的多次修改,最终花了两个多小时才解决了这个问题,可见编程真是步步为营,一点都马虎不得!从输入的读取到核心的算法一直到输出,都要以认真严谨的态度来对待。

当然程序还有许多值得改进的地方,比如多项式的输入和读取缺乏健壮性,对输错的内容无法进行处理等等。无论如何,能比较圆满地完成这个课题对我来说是个极大的鼓舞,它让我享受到了编程的快乐,同时也留下了我成熟的印痕,成为我漫漫编程路上的一个里程碑。

 

你可能感兴趣的:(数据结构课程设计之二—— 一元多项式)