1. 程式人生 > >c語言一元多項式的相加

c語言一元多項式的相加

1. 問題描述
設計一個程式實現兩個一元稀疏多項式的表示及基本操作(建立、銷燬、輸出、加法、減法等操作)。


2. 演算法設計
根據一元多項式相加的運算規則:對於兩個一元多項式中所有指數相同的項,對應指數相加(減),若其和(差)不為零,則構成“和(差)多項式”中的一項;對於兩個一元多
項式中所有指數不相同的項,則分別寫到“和(差)多項式”中去。因為多項式指數最高項以及項數是不確定的,因此採用線性連結串列的儲存結構便於實現一元多項式的運算。
(假定使用者輸入的一元多項式係數從小到大)本程式在構建兩個連結串列完後複製這兩個連結串列,使用者輸入一個一元多項式完畢後,即會在螢幕上打印出相應的一元多項
式,輸入兩個一元多項式完畢後,螢幕上會顯示響應的功能選擇(任意一個功能只能用一次),使用者輸入1或2分別完成加法或減法操作,輸入3退出程式。
3. 演算法實現
系統的執行環境: DevC++
原始碼:




#include<stdio.h>
#include<stdlib.h>
//相加前提 
//假定使用者輸入從小到大 
typedef struct polynomial{
int coef;//係數
int expn;//指數 
struct polynomial *next; 
}polynomial;
polynomial* Copypolynomial(polynomial* h);
void InsFirstsubtract(polynomial *head,polynomial *p,polynomial *q);
void InsFirstadd(polynomial *head,polynomial *p,polynomial *q);
void Insertpolynomial(polynomial* head1,polynomial* s);
void Destroypolynomial(polynomial* head);
void Deletepolynomial(polynomial *head,polynomial *p);
void Union1(polynomial *h1,polynomial *h2);
void Union(polynomial *h1,polynomial *h2);
void subtractpolynomial(polynomial *head1,polynomial *head2);
void addpolynomial(polynomial *head1,polynomial *head2);
int ListEmpty(polynomial *head);
void Displaypolynomial(polynomial* h1);
void SetCurElem(polynomial *p,int sum);
int cmp( polynomial *p,polynomial *q);




polynomial* Createpolynomial()
{   int i=0,j=0,c=0,e=0; 
    polynomial *p,*head;
    head=(polynomial*)malloc(sizeof(polynomial));
    p=head;
    scanf("%d",&i);
    for(j=1;j<=i;j++)


{  // 給個頭指標 這個非常重要 表建立正確是第一步 
 //printf("請分別輸入係數和指數,中間用逗號隔開");
  p->next=(polynomial*)malloc(sizeof(polynomial));
       p=p->next;//指標沒有賦值好 
       printf("係數和指數(中間用空格隔開):");
  scanf("%d %d",&c,&e);//這個中間只能是空格不能是逗號 逗號第二個資料輸入不進去 
  p->coef=c;
  p->expn=e;
  p->next=(polynomial*)malloc(sizeof(polynomial));
  
    
}
p->next=NULL;
return head;
}
polynomial* Copypolynomial(polynomial* h)
{   polynomial *p,*head;
    polynomial *q=h->next;
head=(polynomial*)malloc(sizeof(polynomial));
    p=head;;


   while(q!=NULL)
{  // 給個頭指標 這個非常重要 表建立正確是第一步 
 //printf("請分別輸入係數和指數,中間用逗號隔開");
  p->next=(polynomial*)malloc(sizeof(polynomial));
       p=p->next;//指標沒有賦值好 
  p->coef=q->coef;
  p->expn=q->expn;
  q=q->next;
}
p->next=NULL;
return head;
}
void InsFirstsubtract(polynomial *head,polynomial *p,polynomial *q){
polynomial *s=head;
while(s->next!=p)
{
s=s->next;
}  
q->coef=(q->coef)*-1;
     q->next=s->next;
s->next=q; 
//錯誤程式碼 引起重視 
/*之前 
  r=s->next; 
r==(polynomial*)malloc(sizeof(polynomial));;
r->coef=q->coef;
r->expn=q->expn;
r->next=p;*/      
}


void InsFirstadd(polynomial *head,polynomial *p,polynomial *q){
polynomial *s=head;
while(s->next!=p)
{
s=s->next;
}
     q->next=s->next;
s->next=q; 
//錯誤程式碼 引起重視 
    /*之前 
  r=s->next; 
r==(polynomial*)malloc(sizeof(polynomial));;
r->coef=q->coef;
r->expn=q->expn;
r->next=p;*/      
}


void SetCurElem(polynomial *p,int sum)
{
p->coef=sum;
}
int cmp(polynomial *p,polynomial *q)
{     int a=p->expn;
      int b=q->expn;
if(a<b)
return -1;
else if(a==b)
return 0;
     else    
return 1;
}
void subtractpolynomial(polynomial *head1,polynomial *head2){
polynomial *p=head1->next;
polynomial *q=head2->next;
polynomial *t=NULL;
int sum=0;
while(p!=NULL&&q!=NULL){
switch(cmp(p,q)){
   //A鏈指數小,那就讓A鏈後移
   //加了個pre=p 
case -1:p=p->next; break;
case  0: sum=(p->coef)+((q->coef)*-1);
     if(sum!=0)
 {
 //y=q;
  SetCurElem(p,sum);
                    p=p->next;
  q=q->next;
   //Deletepolynomial(head2,y);
  }
  else {
  t=p;
  p=p->next; 
   Deletepolynomial(head1,t);
   //t=q;
  q=q->next; 
 //Deletepolynomial(head1,t);
  } 
  break;
   //A鏈指數大,那就讓B鏈插入到A鏈當前節點之前,B鏈後移並釋放B鏈當前節點 
case 1:
//在此必須首先讓一個遍歷指標記住B表待插入節點的下一個節點 
   t=q;
   q=q->next; 
 //Deletepolynomial(head2,t);
   InsFirstsubtract(head1,p,t);
break;
default: break;  
}

}

//這裡一定要注意 如果後面有,要讓B表後面的係數是負數 
 if(!ListEmpty(head2)){
         Union1(head1,q);    //尾插法
//Destroypolynomial(head2);
}

}
void addpolynomial(polynomial *head1,polynomial *head2){
polynomial *p=head1->next;
polynomial *q=head2->next;
polynomial *t=NULL,*s=NULL;
int sum=0;
while(p!=NULL&&q!=NULL){
switch(cmp(p,q)){
   //A鏈指數小,那就讓A鏈後移
   //加了個pre=p 
case -1:p=p->next;break;
case  0: sum=(p->coef)+(q->coef);
     if(sum!=0)
 {
 //y=q;
  SetCurElem(p,sum);
                    p=p->next;
  q=q->next;
   //Deletepolynomial(head2,y);  
  }
  else {
  t=p;
  p=p->next; 
   Deletepolynomial(head1,t);
  // t=q;
   q=q->next; 
   //Deletepolynomial(head2,t);
  } 
  break;
   //A鏈指數大,那就讓B鏈插入到A鏈當前節點之前,B鏈後移並釋放B鏈當前節點 
case 1:
//在此必須首先讓一個遍歷指標記住B表待插入節點的下一個節點 
 //Deletepolynomial(head2,t);
   t=q;
               q=q->next;
               
               //特別注意前插的指標記下來,然後出現在引數列表中 
   InsFirstadd(head1,p,t);
  


break;
default: break;  
}


}
 if(!ListEmpty(head2)){
         Union(head1,q);    //尾插法
//Destroypolynomial(head2);
}


    


}


void Union(polynomial *h1,polynomial *h2)
{
polynomial *p=h1->next,*q=h2;
while(q!=NULL) {
    Insertpolynomial(h1,q);
q=q->next;
} 
}


void Union1(polynomial *h1,polynomial *h2)
{
polynomial *p=h1->next,*q=h2;
while(q!=NULL) {
q->coef=-1*(q->coef);
    Insertpolynomial(h1,q);
q=q->next;
} 
}
void Insertpolynomial(polynomial* head1,polynomial* s){
polynomial *q=head1->next,*p=head1->next;//連續定義兩個指標變數是這樣定義的 注意 
    while(q->next!=NULL)
    q=q->next;
q->next=(polynomial*)malloc(sizeof(polynomial));//這裡注意需要個指標變數  否則next太多了 
    p=q->next;
    p->coef=s->coef;
    p->expn=s->expn;
p->next=NULL;
    }


int ListEmpty(polynomial *head){
if(head!=NULL)
return 0;
}


void Deletepolynomial(polynomial* head,polynomial* p){
    polynomial *q=head,*s=p;
while(q->next!=s)
{
q=q->next;
}
q->next=s->next;
free(s);
}
void Destroypolynomial(polynomial* head){
polynomial *p,*q;
p=head;
while(p!=NULL)
{
  q=p->next;
  free(p);
  p=q;
} 
head=NULL;
}


void Displaypolynomial(polynomial* h1) {
if(h1->next!=NULL) {


        polynomial *p=h1->next;
        printf("%dX^%d",p->coef,p->expn);
          p=p->next;
        while(p!=NULL)//判斷條件錯誤 
        {
        if(p->coef>0)
{printf("+");
} 
else{}
printf("%dX^%d",p->coef,p->expn);
        p=p->next;
}
   }
   else{
       printf("兩式子相減已為零,無法輸出!!"); 
   }
 


}
/*int PolynomialLength(polynomial* head)
{
polynomial *p=head;
int o=0;
while(p->next!=NULL){
   o++;
p=p->next; //這裡少個指標移動 
 }
    return o;
}*/








int main(){
int y;
int flag;
polynomial *h1=NULL,*h2=NULL,*h3=NULL,*h4=NULL;
printf("請輸入第一個多項式的節點個數");
h1=Createpolynomial();
printf("多項式A為:"); 
Displaypolynomial(h1);
h3=Copypolynomial(h1);
    printf("\n");
printf("請輸入第二個多項式的節點個數");
h2=Createpolynomial();
printf("多項式B為:"); 
Displaypolynomial(h2);
h4=Copypolynomial(h2);
    printf("\n");
     for(;;) /*實現反覆輸入選擇*/{
    printf("┏━━━━━━━━━━━━━━━━━━┓\n");
    printf("┃請選擇您要進行的操作:              ┃\n");
    printf("┃          1.輸出多項式A+B           ┃\n");
    printf("┃          2.輸出多項式A-B           ┃\n");
    printf("┃          3.退出                    ┃\n");
    printf("┗━━━━━━━━━━━━━━━━━━┛\n");
      fflush(stdin);
      scanf("%d",&flag);
      if(flag==1)
      
      {
 printf("多項式A+B為:");
 addpolynomial(h1,h2);
           Displaypolynomial(h1);
           printf("\n");
 }
 else if(flag==2){
  printf("多項式A-B為:");
   subtractpolynomial(h3,h4);
        Displaypolynomial(h3);
        printf("\n");
 }
else if(flag==3){
printf("\n");
   printf("━━━━━━━感謝使用 ━━━━━━━━\n");
   break;
}
  else 
  {
   printf("━━━━輸入錯誤.請重新輸入!━━━━━\n");


  }
}




return 0;
}



4. 心得體會
充分體會到設計一個程式一定要細緻,再細緻,在C的指標這裡指標如果不小心,就非常容易亂指,要在每次呼叫函式時用指標特別注意,一個完美的程式是需要不斷的用心
當作自己的孩子一樣去構造它,要考慮的方面很多,例如效率,與使用者互動效果好,當前階段最重要的還是要多敲程式碼,多練習,發現問題,解決問題的一個過程,本次的實驗
讓我認識到要想設計一個好的程式,不僅要有好的技術基礎,更要站在使用者使用的角度上去想問題,讓使用者喜歡。以後的路還很長,持之以恆,永不滿足!
5. 參考文獻
資料結構(C語言版)嚴蔚敏