大作业:多项式

翁恺老师的大作业~
实现多项式,之前的写代码没有抄,重新手打优化

//多项式加减乘
//输入格式:x前面为系数,后面为次数 ;不必按次数输入,可打乱,可有空格(会过滤空格) 
//例如:x5+2x3+2 表示x的五次方+2*x的三次方+2
//输出格式:指数递增,正常格式 如上例:2.00+2.00x^3+x^5
//BY Peter_H 
//2019.3.30 22:30--2019.3.31 2:30
//2019.3.31 10:00--2019.3.31 13:09
//2019.3.31 23:00--23:30 改进可支持小数系数 增加指导界面 
//2019.4.2 发现bug 并不能支持小数系数 debug一小时无果 气炸 呜呜
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct node* ptr;
struct ppoly{
	int ex;
	double coef;
};
struct node{
	int ex;
	double coef;
	ptr next;
};//存多项式
void readinput(char *a)//过滤空格 //char* readinput()会出问题 似乎两次调用函数地址没有变 
{
	printf("输入多项式:\n");
	char b[100000];
	//printf("%p\n",a);
	int k=0;
	gets(a);
	for(int i=0;i<strlen(a);i++)
	{
		if(a[i]==' ')continue;
		b[k++]=a[i];
	}
}
int isop(char ch)//判断操作符 
{
	if(ch=='+')return 1;
	else if(ch=='-')return -1;
	else if(ch=='*')return 2;
	else return 0;
}
void createpoly(char *a,struct ppoly poly[])//create poly
{
	int k=0,flag[100000]={0};//负号的处理 
	for(int i=0;i<strlen(a);i++)
	{
		if(isop(a[i])==-1){
			flag[k]=1;
		}
		if(a[i]=='x'){
			if((i-1==0&&a[0]!='-')||(i-1>0&&!isop(a[i-1])))poly[k].coef=a[i-1]-'0';
			else poly[k].coef=1;
			if(i+1<strlen(a)&&!isop(a[i+1]))poly[k].ex=a[i+1]-'0';
			else poly[k].ex=1;
			k++;		
		}
		else if(isdigit(a[i])&&i!=0&&i!=strlen(a)-1&&isop(a[i-1])&&isop(a[i+1]))
		{
			poly[k].ex=0;
			poly[k].coef=a[i]-'0';
			k++;
		}
		else if((isdigit(a[i])&&i==0&&(isop(a[i+1])||i+1==strlen(a)))||(isdigit(a[i])&&i==1&&a[0]=='-'&&isop(a[i+1])))
		{
			poly[k].ex=0;
			poly[k].coef=a[i]-'0';
			k++;
		}
		if(isdigit(a[i])&&i==strlen(a)-1&&isop(a[i-1])){
			poly[k].ex=0;
			poly[k].coef=a[i]-'0';
			k++;
		}
	}
	poly[k].coef=0;
	poly[k].ex=-1;
	for(int i=0;i<k;i++)
	{
		if(flag[i])poly[i].coef*=-1;
	}
	//for(int i=0;i<k;i++)
	//printf("%d ",flag[i]);
	//return poly;
}
void sortpoly(struct ppoly*p)//从小到大排序 冒泡排 
{
	int n=0;
	for(int i=0;p[i].coef!=0;i++)
		n++;
	for(int i=0;i<n;i++)
	{
	 	for(int j=i+1;j<n;j++)
		{
			if(p[i].ex>p[j].ex){
				struct ppoly tmp;
				tmp=p[j];
				p[j]=p[i];
				p[i]=tmp;
			}
		}
	}	
}
void printpoly(struct ppoly*p)//输出多项式数组 
{
	int i;
	for(i=0;p[i].coef!=0;i++)
		printf("%dx_%d ",p[i].coef,p[i].ex);
	if(i==0)printf("0.00");
	printf("\n");
}
void printpolynode(ptr p)//输出多项式链表 
{
	if(p->next)p=p->next;
	else{
		printf("0.00\n");
		return;
	} 
	if(p){
		if(p->coef!=-1&&p->coef!=1&&p->ex>1)printf("%.2lfx^%d",p->coef,p->ex);
		else if(p->coef==1&&p->ex>1)printf("x^%d",p->ex);
		else if(p->coef==-1&&p->ex>1)printf("-x^%d",p->ex);
		else if(p->coef!=-1&&p->coef!=1&&p->ex==1)printf("%dx",p->coef);
		else if(p->coef==1&&p->ex==1)printf("x");
		else if(p->coef==-1&&p->ex==1)printf("-x");
		else if(p->ex==0)printf("%d",p->coef);	
		p=p->next;	
	}
	for(;p;p=p->next)
 	{
 		if(p->coef>1&&p->ex>1)
	  	     printf("+%dx^%d",p->coef,p->ex);
 		else if(p->coef>1&&p->ex==1)
 			 printf("+%dx",p->coef);
 		else if(p->coef==1&&p->ex>1)
 			 printf("+x^%d",p->ex);
 		else if(p->coef==1&&p->ex==1)
 			 printf("+x");
 		else if(p->coef<-1&&p->ex>1)
 			 printf("%dx^%d",p->coef,p->ex);
 		else if(p->coef<-1&&p->ex==1)
 			 printf("%dx",p->coef);
 		else if(p->coef==-1&&p->ex>1)
 			 printf("-x^%d",p->ex);
 		else if(p->coef==-1&&p->ex==1)
 			 printf("-x");
	    else if(p->ex==0)
	    {
	    	if(p->coef>0)printf("+%d",p->coef);
	    	else if(p->coef<0)printf("%d",p->coef);
		}
    }
    printf("\n");
}
void printinput(char* a)//输出数组 debug用 
{
	for(int i=0;i<strlen(a);i++)
			printf("%c",a[i]);
	printf("\n");
}
ptr readpoly(struct ppoly*p)//将多项式结构数组转成多项式链表 
{
	ptr pp,ans;
	pp=(ptr)malloc(sizeof(struct node));
	pp->next=NULL;
	ans=pp;
	for(int i=0;p[i].coef!=0;i++)
	{
		ptr tmp=(ptr)malloc(sizeof(struct node));
		tmp->coef=p[i].coef;
		tmp->ex=p[i].ex;
		tmp->next=NULL;
		pp->next=tmp;
		pp=pp->next;
	}
	return ans;
}
ptr addpoly(struct node*p1,struct node*p2)//多项式加法 
{
	//printf("多项式加减法。\n");
	ptr p,ans,pp1,pp2;
	pp1=p1->next;
	pp2=p2->next;
	p=(ptr)malloc(sizeof(struct node));
	p->next=NULL;
	ans=p;
	while(pp1&&pp2)
	{
		//printf("$$%d %d$$\n",p->coef,p->ex);
		if(pp1->ex<pp2->ex){
			ptr tmp=(ptr)malloc(sizeof(struct node));
			tmp->next=NULL;
			tmp->coef=pp1->coef;
			tmp->ex=pp1->ex;
			p->next=tmp;//这里如果不弄tmp 直接p->next=pp1 后面可能会把pp1改掉 
			p=p->next;
			pp1=pp1->next;
		}
		else if(pp1->ex>pp2->ex)
		{
		    ptr tmp=(ptr)malloc(sizeof(struct node));
			tmp->next=NULL;
			tmp->coef=pp2->coef;
			tmp->ex=pp2->ex;
			p->next=tmp;
			p=p->next;
			pp2=pp2->next;
		}
		else{
			ptr tmp=(ptr)malloc(sizeof(struct node));
			tmp->next=NULL;
			tmp->coef=pp1->coef+pp2->coef;
			tmp->ex=pp1->ex;
			if(tmp->coef){
				p->next=tmp;
				p=p->next;
				pp1=pp1->next;
				pp2=pp2->next; 
			}
			else {
				free(tmp);
			//	p=p->next;
				pp1=pp1->next;
				pp2=pp2->next; 
			}
		}
	}
	if(pp1)p->next=pp1;
	if(pp2)p->next=pp2;
	return ans;
}
ptr substractpoly(struct node*p1,struct node*p2)//多项式减法 为poly1-poly2 首先把poly2变成相反数 然后调用加法 
{
	ptr mp2,ans;
	mp2=(ptr)malloc(sizeof(struct node));
	mp2->next=NULL;
	ans=mp2;
	if(p1->next==NULL&&p2->next==NULL)return ans;
	p2=p2->next;
	while(p2)
	{
		ptr tmp=(ptr)malloc(sizeof(struct node));
		tmp->next=NULL;
		tmp->coef=-p2->coef;
		tmp->ex=p2->ex;
		mp2->next=tmp;
		p2=p2->next;
		mp2=mp2->next;
	}
	
	return addpoly(p1,ans);
}
ptr multipoly(struct node*p1,struct node*p2)//多项式乘法 先乘一组,然后再乘后面的,插入 
{
	//printf("多项式乘法。\n");
	ptr phead,p,tmp,pp1,pp2,ans,pp2h;
	pp1=p1->next;
	pp2=p2->next;
	pp2h=pp2;
	p=(ptr)malloc(sizeof(struct node));
	p->next=NULL;
	ans=p;
	if(pp1==NULL||pp2==NULL)return p;
	while(pp2){
		ptr tmp=(ptr)malloc(sizeof(struct node));
		tmp->next=NULL;
		tmp->coef=pp1->coef*pp2->coef;
		tmp->ex=pp1->ex+pp2->ex;
		p->next=tmp;
		p=p->next;
		pp2=pp2->next;
	}
	pp1=pp1->next;
	while(pp1)
	{
		pp2=pp2h;
		while(pp2)
		{
			ptr tmp=(ptr)malloc(sizeof(struct node));
			tmp->next=NULL;
			tmp->coef=pp1->coef*pp2->coef;
			tmp->ex=pp1->ex+pp2->ex;
			ptr q1=ans,q=q1->next;
			while(q&&q->ex<tmp->ex)
				{
					q=q->next;
					q1=q1->next;
				}
			if(q)
			{
				if(q->ex==tmp->ex){
					q->coef+=tmp->coef;
					if(q->coef){
						pp2=pp2->next;	
						continue;				
					}
					else{
						q1->next=q->next;
						free(q);
					}
				}
			else  {
				tmp->next=q->next;
				q->next=tmp;	//插入		
			}
			}
			else {
				if(tmp->coef)
				{
					p->next=tmp;
					p=p->next;
				}
			}
			pp2=pp2->next;		
		}
		pp1=pp1->next;
		 
	}
	return ans;
	
}
int main()
{
	ptr p1,p2,padd,psubstract,pmulti;
	struct ppoly poly1[10000],poly2[10000];
	char a[100000],b[100000];
	printf("这是一个多项式运算器。\n");
	printf("你可以用它来计算多项式加法、减法、乘法。系数只能为十以内整数。\n");
 	printf("例如:如果要输入x的三次方加2x的平方加3,直接输“x3+2x2+3”即可。\n");
	readinput(a);
	readinput(b);
//	printinput(a);
//	printinput(b);
	createpoly(a,poly1);
	createpoly(b,poly2);
	sortpoly(poly1);
	sortpoly(poly2);
	//printpoly(poly1);
	//printpoly(poly2);
	p1=readpoly(poly1);
	p2=readpoly(poly2); 
//	printpolynode(p1);
//	printpolynode(p2);
	padd=addpoly(p1,p2);//多项式加法
	psubstract=substractpoly(p1,p2);//多项式减法 
	pmulti=multipoly(p1,p2);//多项式乘法 
	printf("两多项式相加得:\n");
	printpolynode(padd);
	printf("两多项式相减得:\n");
	printpolynode(psubstract);
	printf("两多项式相乘得:\n");
	printpolynode(pmulti);
	return 0;
}
	




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值