之前的多项式本质是数组实现的,而且转换了好几次,受内存空间限制,更难过的是又发现了不能正确算带小数系数的多项式的bug,修了一个小时无果。
在一个月黑风高的夜晚,三千五跑完后偶遇求计学长,一番指点后决定重写。
一个一个读入,边读边判断,重写了一下排序函数,现在可以了!
//多项式加减乘
//输入格式:x前面为系数,后面为次数 ;不必按次数输入,可打乱,可有空格(会过滤空格)
//例如:x5+2x3+2 表示x的五次方+2*x的三次方+2
//输出格式:指数递增,正常格式 如上例:2.00+2.00x^3+x^5
//BY Peter_H
//2019.4.5 21:30--24:30
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct node* ptr;
struct node{
int ex;
double coef;
ptr next;
};//存多项式
int isop(char ch)//判断操作符
{
if(ch=='+')return 1;
else if(ch=='-')return -1;
else if(ch=='*')return 2;
else return 0;
}
ptr createpoly()//创建链表存多项式边读边判断
{
ptr ans,tmp,p;
char ch;
p=(ptr)malloc(sizeof(struct node));
p->next=NULL;
ans=p;
ch=getchar();
char d[1000]={'\0'};
int k=0,flag=1;
while(ch!='\n')
{
while(ch==' ')
{
ch=getchar();
continue;
}
while(ch=='.'||isdigit(ch)){
d[k++]=ch;
ch=getchar();
while(ch==' ')
{
ch=getchar();
continue;
}
}
if(isop(ch))
{
if(k)
{
tmp=(ptr)malloc(sizeof(struct node));
tmp->next=NULL;
tmp->coef=flag*atof(d);
flag=1;
tmp->ex=0;
p->next=tmp;
p=p->next;
memset(d,'\0',sizeof(d));
k=0;
}//1.5+...
if(ch=='-')flag=-1;
else if(ch=='+')flag=1;
ch=getchar();
}
if(ch=='x')
{
if(k==0)
{
tmp=(ptr)malloc(sizeof(struct node));
tmp->next=NULL;
tmp->coef=flag;
flag=1;
ch=getchar();
while(ch==' ')
{
ch=getchar();
continue;
}
if(isop(ch))//x+...
{
if(ch=='-')flag=-1;
else if(ch=='+')flag=1;
tmp->ex=1;
p->next=tmp;
p=p->next;
}
else if(isdigit(ch)) //x2+...
{
tmp->ex=ch-'0';
p->next=tmp;
p=p->next;
}
else if(ch=='\n')//x
{
tmp->ex=1;
p->next=tmp;
p=p->next;
break;
}
ch=getchar();
}
else//1.5x2+...
{
tmp=(ptr)malloc(sizeof(struct node));
tmp->next=NULL;
tmp->coef=flag*atof(d);
flag=1;
memset(d,'\0',sizeof(d));
k=0;
ch=getchar();
while(ch==' ')
{
ch=getchar();
continue;
}
if(isop(ch))
{
if(ch=='-')flag=-1;
else if(ch=='+')flag=1;
tmp->ex=1;
p->next=tmp;
p=p->next;
}
else if(isdigit(ch))//1.5x2
{
tmp->ex=ch-'0';
p->next=tmp;
p=p->next;
}
else if(ch=='\n')//1.5x
{
tmp->ex=1;
p->next=tmp;
p=p->next;
break;
}
ch=getchar();
}
}
if(ch=='\n'&&k)
{
tmp=(ptr)malloc(sizeof(struct node));
tmp->next=NULL;
tmp->coef=flag*atof(d);
flag=1;
tmp->ex=0;
p->next=tmp;
p=p->next;
memset(d,'\0',sizeof(d));
k=0;
}
}
return ans;
}
void sortpoly(ptr poly)//从小到大排序 冒泡排
{
ptr q,p;
q=poly->next;
if(q)p=q->next;
while(q)
{
while(p)
{
if(q->ex>p->ex)
{
int tmp2;
double tmp1;
tmp1=q->coef;
q->coef=p->coef;
p->coef=tmp1;
tmp2=q->ex;
q->ex=p->ex;
p->ex=tmp2;
}
p=p->next;
}
q=q->next;
if(q)p=q->next;
}
//合并系数
ptr pp=poly->next;
while(pp)
{
if(pp->next)
{
if(pp->ex==pp->next->ex)
{
ptr q=pp;
while(pp->next&&q->ex==pp->next->ex)
{
pp=pp->next;
q->coef+=pp->coef;
}
pp=pp->next;
q->next=pp;
}
else pp=pp->next;
}
else pp=pp->next;
}
//删除0项
ptr ppp=poly->next;
while(ppp)
{
if(ppp->next==NULL&&ppp->coef==0)poly->next=NULL;
else if(ppp->next&&ppp->next->coef==0)
{
ptr tmp=(ptr)malloc(sizeof(struct node));
tmp=ppp->next;
ppp->next=tmp->next;
free(tmp);
}
if(ppp)ppp=ppp->next;
}
}
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("%.2lfx",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("%.2lf",p->coef);
p=p->next;
}
for(;p;p=p->next)
{
if(p->coef>1&&p->ex>1)
printf("+%.2lfx^%d",p->coef,p->ex);
else if(p->coef>1&&p->ex==1)
printf("+%.2lfx",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("%.2lfx^%d",p->coef,p->ex);
else if(p->coef<-1&&p->ex==1)
printf("%.2lfx",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("+%.2lf",p->coef);
else if(p->coef<0)printf("%.2lf",p->coef);
}
}
printf("\n");
}
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 poly1,poly2,padd,psubstract,pmulti;
printf("这是一个多项式运算器。\n");
printf("你可以用它来计算多项式加法、减法、乘法。系数默认保留两位小数。\n");
printf("例如:如果要输入x的三次方加2x的平方加3,直接输“x3+2x2+3”即可。\n");
poly1=createpoly();
poly2=createpoly();
sortpoly(poly1);
sortpoly(poly2);
//printpolynode(poly1);
//printpolynode(poly2);
padd=addpoly(poly1,poly2);//多项式加法
psubstract=substractpoly(poly1,poly2);//多项式减法
pmulti=multipoly(poly1,poly2);//多项式乘法
printf("两多项式相加得:\n");
printpolynode(padd);
printf("两多项式相减得:\n");
printpolynode(psubstract);
printf("两多项式相乘得:\n");
printpolynode(pmulti);
return 0;
}