【实验】一元多项式的相加与相乘

数据结构上机实验。


实验要求:

根据所给的一元多项式相加的程序,写出一元多项式相乘的程序并调试通过。


注意:

1、最后得到的一元多项式采用两种输出格式,即数字格式和一般格式。

2、一般格式的多项式输出,按指数非递增顺序。

3、系数为0的项不予以输出(只有0项的多项式只输出0)。


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define null 0
typedef struct 
{
	float coef;
	int expn;
}term;
typedef struct Lnode
{
	term data;
	Lnode *next;
}*Link,*Linklist;

//比较函数,依a的指数值<(或=、或>)b的指数值,分别返回+1、0、和-1
int cmp (term a,term b);
//定位
int LocateElem(Linklist L,term e,Link &s,Link &q,int(*comp)(term,term)); 
//删除结点 
void Delnext(Linklist &L,Link s);
//顺序插入 
void Orderinsert(Linklist &L,term e,int (*comp)(term,term));
//顺序混合插入 
void Orderinsertmerge(Linklist &L,term e,int(*compara)(term,term));
//建立链表 
void Creatpolyn(Linklist &p,int m);
//销毁链表 
void DestroyList(Linklist &L);
//完成多项式相加运算 
void add(Linklist &La,Linklist &Lb);
//完成多项式相乘运算 
void mul(Linklist &La,Linklist &Lb,Linklist &Lc);
//一元多项式输出方式1
void printpolyn(Linklist p);
//一元多项式输出方式2
void printpolyn2(Linklist p);


int main()
{
	int x;
	char s1[2],s2[2];
	Linklist L1,L2,L3;
	while(1)
	{
		printf("\n请输入第一个一元多项式的项数:");
		scanf("%d",&x);
		Creatpolyn(L1,x);
		printpolyn(L1);
		
		printf("\n请输入第二个一元多项式的项数:");
		scanf("%d",&x);
		Creatpolyn(L2,x);
		printpolyn(L2);
	
		printf("\n(1)加法 (2)乘法,请输入1 or 2:");
		scanf("%s",s1);
		if(s1[0]=='1')
		{
			add(L1,L2);
			printf("\n相加以后的一元多项式为:\n");
			printpolyn(L1);
			printpolyn2(L1);
		}
		else
		{
			Creatpolyn(L3,0);	
			mul(L1,L2,L3);
			printf("\n相乘以后的一元多项式为:\n");
			printpolyn(L3);
			printpolyn2(L3);
		}
		printf("\n是否继续输入 yes or no:"); 
		scanf("%s",s2);
		
		if(s2[0]!='y')
		break;
	}
	return 0;
}

int cmp (term a,term b)
{
	if(a.expn==b.expn) return 0;
	else return -(a.expn-b.expn)/abs(a.expn-b.expn);
}

int LocateElem(Linklist L,term e,Link &s,Link &q,int(*comp)(term,term))
{
	Link p;
	s=L;
	p=s->next;    
	while(p&&comp(p->data,e)!=0)
	{
		s=p;p=p->next;
	}
	if(!p)	{	s=q=null;	return 0;}
	else	{	q=p;	return 1;}
}

void Delnext(Linklist &L,Link s)
{
	Link  q=s->next;
	s->next=q->next;
	free(q);
}

void Orderinsert(Linklist &L,term e,int (*comp)(term,term))
{
	Link o,p,q;
	q=L;
	p=q->next;
	while(p&&comp(p->data,e)<0)
	{
		q=p;p=p->next;
	}
	o=(Link)malloc(sizeof(Lnode));
	o->data=e;
	q->next=o;
	o->next=p;
}

void Orderinsertmerge(Linklist &L,term e,int(*compara)(term,term))
{
	Link q,s;
	if(LocateElem(L,e,s,q,compara))		//已存在与x指数相等项,则系数相加。 
	{
		q->data.coef+=e.coef;
		if(!q->data.coef)				//如果当前data.coef==0,则删除结点,s指向q的前驱 
		{
			Delnext(L,s);
		}
	}
	else Orderinsert(L,e,compara);		//若不存在,则顺序插入新节点 
}

void Creatpolyn(Linklist &p,int m)
{
	term e;
	int i;
	p=(Link)malloc(sizeof(Lnode));		//建立头结点 
	p->next=null;
	if(!m) return ;						//当m==0,不执行下面的语句(为了建立Lc表) 
	printf("\n请输入%d个系数和指数,用空格符隔开:\n",m);
	for(i=1;i<=m;i++)
	{
		scanf("%f%d",&e.coef,&e.expn);
		Orderinsertmerge(p,e,cmp);
	}
}

void DestroyList(Linklist &L)			//销毁链表 
{
	Link p;
	while(L->next)
	{
		p=L->next;	L->next=p->next;
		free(p);
	}
	free(L);
}

void add(Linklist &La,Linklist &Lb)		//实现加法运算,用顺序混合插入函数实现 
{
	Link qb;
	term b;
	qb=Lb->next;
	while(qb)
	{
		b=qb->data;
		Orderinsertmerge(La,b,cmp);
		qb=qb->next;
	}
	DestroyList(Lb);					//销毁Lb链表 
}

void mul(Linklist &La,Linklist &Lb,Linklist &Lc)		//实现乘法运算,完成后销毁La、Lb链表 
{
	Link qa,qb,qc;
	term e;
	qa=La->next;
	qc=Lc;
	while(qa)
	{
		qb=Lb->next;
		while(qb)
		{
			e.coef = qa->data.coef * qb->data.coef;
			e.expn = qa->data.expn + qb->data.expn;
			if(e.coef != 0.0) Orderinsertmerge(qc,e,cmp);
			qb=qb->next;
		}
		qa=qa->next;
	}
	DestroyList(La);						
	DestroyList(Lb);
}

void printpolyn(Linklist p)
{
	Link q;
	q=p->next;
	printf("	系数	指数\n");
	if(q==null)
	{	printf("	0	0\n"); return ;}
	while(q)
	{
		printf("%8.2f	%-d\n",q->data.coef,q->data.expn);
		q=q->next;
	}
}

void printpolyn2(Linklist p)
{
	Link q;
	q=p->next;
	printf("P(x) = ");
	if(q==null)
	{	printf("0\n"); return ;}
	printf("%.2f*X^%d ",q->data.coef,q->data.expn);
	q=q->next;
	while(q)
	{
		if(q->data.coef>0)
		printf("+ %.2f*X^%d ",q->data.coef,q->data.expn);
		else  if(q->data.coef<0)
		printf("- %.2f*X^%d ",-q->data.coef,q->data.expn);
		q=q->next;
	}
	printf("\n");
}


测试数据一(选择1为加法):
3
1 1
2 2
3 3
2
1 2
2 3
1




测试数据二(选择2为乘法):
3
1 1
2 2
3 3
2
1 2
2 3
2




测试数据三(相加后出现系数为0的情况):
3
1 1
2 2
3 3
2
-1 1
-2 2
1




测试数据四(相加后结果只有0项):
1
-1 1
1
1 1
1


















评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值