資料結構—— 一元多項式的運算(相加,相減,相乘)【C語言實現】
阿新 • • 發佈:2018-12-18
用 C語言實現一元多項式的運算(相加,相減,相乘)
1.建立多項式時,無論指數項按什麼順序輸入,輸出均能實現以升冪順序輸入,且輸入時有相同指數項時能夠實現合併。 2.能夠代入確切的X計算出最終多項式的值。 模組劃分 1.模組劃分:本程式劃分為9個模組,分別是: 1.主函式模組, 2.LocateElem模組(定位排序), 3.CreatePolyn模組(建立多項式), 4.AddPolyn模組(多項式相加), 5.PrintPolyn模組(列印多項式), 6.SubPolyn模組(多項式相減), 7.Reverse模組(升冪,降冪), 8.MultiplyPolyn模組(多項式相乘), 9.Calculate模組(代入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);
}
程式碼測試 輸入時多項式時每項的冪按亂序輸入,且兩個多項式中有抵消項時:
輸入時多項式時每項的冪按亂序輸入,兩個多項式相乘:
Over!!!