翁恺老师的大作业~
实现多项式,之前的写代码没有抄,重新手打优化
//多项式加减乘
//输入格式: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;
}