資料結構——一元多項式的運算(相加,相減,相乘)【C語言實現】
阿新 • • 發佈:2018-12-18
實現一元多項式的運算(相加,相減,相乘)
1.輸入多項式時無論以何種順序輸入,都能夠以升冪順序輸出,且有相同指數項時能夠合併。 2.實現相加,相減,相乘功能。 3.能夠代入確切的X的值求取最終多項式的值。
#include<stdio.h> #include<stdlib.h> #include<math.h> #define LEN sizeof(Poly) typedef struct term{ float coef; //係數 int expn; //指數 struct term *next; }Poly,*Link; int LocateElem(Link p, Link s, Link &q); void CreatePolyn(Link &p,int m); //建立多項式 void PrintPolyn(Link p); //列印多項式(表示) int cmp(Link a, Link b); Link AddPolyn(Link pa, Link pb); //多項式相加 Link SubPolyn(Link pa, Link pb); //多項式相減 Link Reverse(Link p); //逆置多項式 Link MultiplyPolyn(Link A,Link B); //多項式相乘 void Calculate(Link p,float x); //多項式求值 int main() { Link P1,P2,P3; //多項式 int L1,L2; //多項式長度 printf(" -------------------------------------------------------------------\n"); printf(" |================== 一元多項式的運算 =================|\n"); printf(" |================== 1.相加(+) =================|\n"); printf(" |================== 2.相減(-) =================|\n"); printf(" |================== 3.相乘(*) =================|\n"); printf(" -------------------------------------------------------------------\n\n"); printf("請輸入第一個多項式的項數:"); scanf("%d",&L1); CreatePolyn(P1,L1); printf("第一個多項式為:"); printf("P1(X)="); PrintPolyn(P1); printf("請輸入第二個多項式的項數:"); scanf("%d",&L2); CreatePolyn(P2,L2); printf("第二個多項式為:"); printf("P2(X)="); PrintPolyn(P2); printf("\n"); printf("請輸入要選擇的運算(+ , - , *): "); char ch1; getchar(); //清除掉緩衝區的回車符 scanf("%c",&ch1); getchar(); //清除掉緩衝區的回車符 switch(ch1){ case '+':{ printf("兩個一元多項式相加: "); printf("P1(X)+P2(X)="); P3=AddPolyn(P1, P2); PrintPolyn(P3); }break; case '-':{ printf("兩個一元多項式相減: "); printf("P1(X)-P2(X)="); P3=SubPolyn(P1, P2); PrintPolyn(P3); }break; case '*':{ printf("兩個一元多項式相乘: "); printf("P1(X)*P2(X)="); P3=MultiplyPolyn(P1, P2); PrintPolyn(P3); }break; default:printf("您輸入了錯誤指令 %c !",ch1); } char ch2; printf("\n是否代入X進行求值?(Y/N): "); ch2=getchar(); //清除掉緩衝區的回車符 getchar(); switch(ch2){ case 'Y':{ float x; printf("\n請輸入多項式中X的值:"); scanf("%f",&x); Calculate(P3,x); break; } case 'N':break; default:printf("你輸入了錯誤指令 %c !",ch2); } return 0; } int LocateElem(Link p, Link s, Link &q){ /*遍歷連結串列p,每一個結點與s比較指數, 若相同,q指向相同指數項的結點,返回1, 若不相同,根據s所指指數大小在連結串列p中的位置來確定q的指向結點,返回0 */ Link p1 = p->next; Link p2 = p; while(p1){ if(s->expn > p1->expn){ p1 = p1->next; p2 = p2->next; }else if(s->expn == p1->expn){ q = p1; return 1; }else{ q = p2; return 0; } } if(!p1){ q = p2; return 0; } } void CreatePolyn(Link &p,int m) /*建立帶頭結點的連結串列(多項式) 且無論按什麼順序輸入,或是有相同指數項 最終在多項式中都是升冪順序! */ { Link s,q; int i; p=(Link)malloc(LEN); p->next=NULL; for(i=0;i<m;i++) { s=(Link)malloc(LEN); printf("輸入係數和指數(以空格隔開):"); scanf("%f %d", &s->coef, &s->expn); if(!LocateElem(p, s, q)){ //若沒有相同指數項,則鏈入 s->next = q->next; q->next = s; }else{ //若有相同指數項,則係數相加 q->coef+=s->coef; } } } void PrintPolyn(Link p) //列印顯示多項式 { Link s; s = p->next; while(s) { printf(" %.2f X^%d", s->coef, s->expn); s = s->next; if(s!=NULL) if(s->coef>=0) printf(" +"); //若下一項係數為正,則列印'+',否則不列印 } printf("\n"); } int cmp(Link a, Link b) //比較兩結點指數大小,根據情況返回不同值 { if (a->expn<b->expn) return -1; else if(a->expn == b->expn) return 0; else return 1; } Link AddPolyn(Link pa, Link pb)//pa,pb均指向頭結點 //兩個多項式相加得一個新多項式,並且返回新多項式的頭結點的指標 { Link newp, p, q, s, pc; float sum; p = pa->next; q = pb->next; newp=(Link)malloc(LEN); //新多項式的頭結點 pc = newp; //pc指向新多項式的頭結點 while(p&&q){ switch(cmp(p, q)) { case -1:// //若指數:p<q,則將p所指結點鏈入頭結點為newp的連結串列中,且p向後遍歷 s = (Link)malloc(LEN); s->coef = p->coef; s->expn = p->expn; pc->next = s; pc = s; p = p->next; break; case 0://若比較兩項的指數相等,則將兩項係數相加後得到的項放入頭結點為newp的連結串列中 ,且p,q同時向後遍歷 sum = p->coef+q->coef; if(sum!=0.0)//若兩項係數相加為0,則不放入頭結點為newp的連結串列中 { s = (Link)malloc(LEN); s->coef = sum; s->expn = p->expn; pc->next = s; pc = s; } p = p->next; q = q->next; break; case 1://若指數:q<p,則將q所指結點鏈入頭結點為newp的連結串列中,且q向後遍歷 s = (Link)malloc(LEN); s->coef = q->coef; s->expn = q->expn; pc->next = s; pc = s; q = q->next; break; } } pc->next=p?p:q;//鏈入pa或pb的剩餘項 return newp;//返回新多項式的頭指標 } Link SubPolyn(Link pa, Link pb) /*兩個多項式相減得一個新多項式,並且返回新多項式的頭結點的指標 相減就是先將減數中每一項的係數變為負,再將兩個多項式相加 */ { Link newp, p, q, s, pc; float sum; newp=(Link)malloc(LEN); pc = newp; p = pa->next; q = pb->next; while(q){// 將pb中每一項的係數變為負 q->coef=0-q->coef; q=q->next; } q=pb->next; while(p&&q){ switch(cmp(p, q)) { case -1: s = (Link)malloc(LEN); s->coef = p->coef; s->expn = p->expn; pc->next = s; pc = s; p = p->next; break; case 0: sum = p->coef-q->coef; if(sum!=0.0) { s = (Link)malloc(LEN); s->coef = sum; s->expn = p->expn; pc->next = s; pc = s; } p = p->next; q = q->next; break; case 1: s = (Link)malloc(LEN); s->coef = q->coef; s->expn = q->expn; pc->next = s; pc = s; q = q->next; break; } } pc->next=p?p:q; return newp; } Link Reverse(Link p) /*用頭插法逆置連結串列, 使多項式由降冪變成升冪順序 或使多項式由升冪變成降冪順序 */ { Link head=p; Link q1,q2; q2=head->next; head->next=NULL;//斷開頭結點與第一個結點 while(q2) { q1=q2; q2=q2->next; q1->next=head->next; //頭插 head->next=q1; } return head;//返回連結串列逆置後的頭結點 } Link MultiplyPolyn(Link A,Link B) /*兩個多項式相乘得一個新多項式,並且返回新多項式的頭結點的指標 相乘前,A,B兩個多項式均是升冪排序 相乘時,A為降冪排序,B為升冪排序 */ { Link pa,pb,pc,s,head; int k,maxExpn,minExpn; float coef; head=(Link)malloc(LEN);//頭結點 head->next=NULL; if(A->next!=NULL&&B->next!=NULL){ minExpn=A->next->expn+B->next->expn; //minExpn為兩個多項式中指數和的最小值 A=Reverse(A);//將A降冪排列 B=Reverse(B);//將B降冪排列 maxExpn=A->next->expn+B->next->expn; //maxExpn為兩個多項式中指數和的最大值 } else{ return head; } pc=head; B=Reverse(B);//將B升冪排列 for(k = maxExpn;k>=minExpn;k--){ //多項式的乘積指數範圍為:minExpn~maxExpn //根據兩項的指數和使每一次迴圈都得到新多項式中一項 pa = A->next; while(pa !=NULL&&pa->expn>k){ //找到pa的位置 pa = pa->next; } pb = B->next; while(pb!=NULL&&pa!=NULL&&pa->expn+pb->expn<k){//如果指數和和小於k,pb後移結點 pb = pb->next; } coef=0.0; while(pa!=NULL&&pb!=NULL){ if(pa->expn+pb->expn==k){ //如果指數和等於k,係數和累加,且pa,pb均後移結點 coef+=pa->coef*pb->coef; pa=pa->next; pb=pb->next; } else if(pa->expn+pb->expn>k){//如果指數和大於k,pb後移結點 pa = pa->next; } else{//如果指數和和小於k,pb後移結點 pb = pb->next; } } if(coef!=0.0){ //如果係數和不為0,則生成新結點,將係數和指數賦給新結點後插入到新多項式中 s=(Link)malloc(LEN); s->coef=coef; s->expn=k; s->next=pc->next; pc->next=s; pc=s; } } B = Reverse(B); head=Reverse(head); return head; //返回新多項式的頭結點 } void Calculate(Link p,float x) //代入確定的x到多項式中求值 { Link q=p->next; float sum; float result=0;//求的結果 while(q){ sum=1.0; for(int i=1;i<=q->expn;i++){//先求每一項的 X^expn 的值 sum=sum*x; } result+=sum*q->coef; //再使係數與sum相乘後求每一項的值,最後累加 q=q->next; } printf("將X的值代入多項式中計算的結果為:%.5f\n",result); }
相加:
相乘: