应用1 一元多项式
a0+a1 * x1+a2 * x2+……这样的式子就是一元多项式了,只有一个变量且为指数项相加的形式。
理论上用一个结构体数组就行了,但是呢,如果是a0 + a100 * x100这样的,要是一个数组,血亏。
所以呢,链表就出来拯救世界了,此时结构体的数值域就应该是两个变量了,exp(指数)和coef(系数)
操作有加减乘除。(输入可以是无序的,在创建里面顺便排序,并处理指数相同的)
那个啥,写程序的时候默认了输入的系数都是正的。。。要是需要负值输入,就要将减法里面判断系数为零的部分加到加法里面。
1.加减
加减就是将两个有序的链表的每一项进行比较,取一个作为返回的,另一个销毁。
比较的结果,无非是 大于、小于、等于,分开讨论即可。
减法就是将加法里面的加改成了减。
另外,如果要销毁的链表在返回的链表结束了之后还没完,加法直接接上去就行,减法要有一个取反的操作,
以及在有空表的情况,加减法有所出入,剩下的基本上相似。
(减法还看到了一个思路,就是直接将减数链表里面系数取反做加法)
2.乘法
简单粗暴一点,我是直接创建新链表,然后每一项都乘一下,不管指数大小都放在新表中, 时间复杂度 o(m*n)
然后再插入到需要返回的链表的合适位置,并合并指数一样的。
(个人感觉在乘的同时解决指数的问题很困难,这样相对明了一点。)
3.除法
emm这个先咕了,因为上网找也没找到思路,有一些没有,有一些看着很诡异(可能是自己没领会到人家的深意)
然后贴代码:
#include <iostream>
//线性链表的应用,存储一元多项式并且加减乘除操作
using namespace std;
struct link
{
int coef;//系数
int exp;//指数
struct link* next;
};
struct link* New_link()
{
cout<< "Do you want a new code?"<<endl;
struct link* head=(struct link* )malloc(sizeof(struct link));
head->next=NULL;
struct link* pr=head;
char judge;
cin>>judge;
while(judge=='y')
{
int exp,coef;
cout << "Input the coef and the exp"<<endl;//输入
cin>>coef;
cin>>exp;
pr=head;
while(pr->next)//看看有没有重复指数的
{
if(pr->next->exp==exp)
{
pr->next->coef+=coef;
coef=0;
break;
}
else
pr=pr->next;
}
if(!coef)//系数为0或者是已经处理的了
{
cout<< "Do you want more?"<<endl;
cin>>judge;
continue;
}
struct link* p=(struct link* )malloc(sizeof(struct link));
p->coef=coef;
p->exp=exp;
pr=head;
while(pr->next)//寻找适合的插入位置,指针在链表当前的前一个位置方便插入
{
if(p->exp > pr->next->exp)
{
pr = pr->next;
}
else//找到了
break;
}
p->next=pr->next;
pr->next=p;
cout<< "Do you want more?"<<endl;
cin>>judge;
}
return head;
}
void deleted(struct link* head)//销毁链表
{
struct link* p=head,*pr=NULL;
while(p)
{
pr=p;
p=p->next;
free(pr);
}
free(head);
}
struct link* add(struct link* heada,struct link* headb)//相加的结果在a表里
{
if(!heada->next)//a空
{
heada->next=headb->next;
free(headb);
return heada;
}
if(!headb->next)//b空
{
free(headb);
return heada;
}
struct link* pa=heada,*pb=headb->next;//老规矩,被插入的要往前一位,便于插入
while(pa->next&&pb)
{
if(pa->next->exp < pb->exp)//a往后走
pa=pa->next;
else if(pa->next->exp==pb->exp)//相同,合并
{
struct link* temp=pb;
pb=pb->next;
pa->next->coef += temp->coef;
free(temp);
}
else//b小,要插入
{
struct link* temp=pb;
pb=pb->next;
temp->next=pa->next;
pa->next=temp;
pa=pa->next;
}
}
if(pb)//b表没完,直接接上
{
pa->next=pb;
}
free(headb);
return heada;
}
struct link* subtraction(struct link* heada,struct link* headb)//相减同样结果在a里面
{
if(!headb->next)//b空
{
free(headb);
return heada;
}
else if(!heada->next)//a空,这时b里面的每一项要取反
{
heada->next=headb->next;
free(headb);
struct link* p=heada->next;
while(p)
{
p->coef = -p->coef;
p = p->next;
}
return heada;
}
struct link* pa=heada,*pb=headb->next;
while(pa->next&&pb)
{
if(pa->next->exp < pb->exp)
pa=pa->next;
else if(pa->next->exp == pb->exp)
{
struct link* temp=pb;
pb=pb->next;
pa->next->coef-=temp->coef;
free(temp);
if(!pa->next->coef)//如果刚好抵消
{
temp=pa->next;
pa->next = temp->next;
free(temp);
}
}
else
{
struct link* temp=pb;
pb=pb->next;
temp->coef=-temp->coef;
temp->next=pa->next;
pa->next=temp;
}
}
while(pb)
{
pb->coef= -pb->coef;
pa->next=pb;
pb=pb->next;
}
free(headb);
return heada;
}
struct link* multiplication(struct link* heada,struct link* headb)//乘法
{
struct link* pa=heada->next, *pb=headb->next;
struct link* headc=(struct link* )malloc(sizeof(struct link));//直接塞到这个链表里面,然后再放到a中同时处理
headc->next=NULL;
struct link* pc=headc;
if(!(pa&&pb))//有一个为空
return NULL;
while(pb)//双重循环保证每一个都有被乘
{
pa=heada->next;
while(pa)
{
struct link* p = (struct link* )malloc(sizeof(struct link));//尾插c表
p->coef = pa->coef * pb->coef;
p->exp = pa->exp + pb->exp;
p->next = pc->next;
pc->next = p;
pc = pc->next;//保证pc在最后
pa = pa->next;
}
pb=pb->next;
}
deleted(headb);
deleted(heada->next);//删除头节点之外的点
heada->next=NULL;//这个别忘了
struct link* temp=headc->next;//先将第一个插入,不然循环跑不起来
pc=temp->next;
headc->next=pc;
temp->next=heada->next;
heada->next=temp;
while(pc)//将headc里面的整合到heada里面
{
struct link* p=heada;
while(p->next)
{
if(p->next->exp == pc->exp)
{
p->next->coef += pc->coef;
pc=pc->next;
break;
}
else if(p->next->exp > pc->exp)//插入
{
temp=pc;
pc=pc->next;
temp->next=p->next;
p->next=temp;
break;
}
else
p=p->next;
}
if(!p->next)//没有合适的位置,尾插
{
temp = pc;
pc=pc->next;
temp->next=p->next;
p->next = temp;
}
}
deleted(headc);
return heada;
}
int main()
{
struct link* heada=New_link(),*headb=New_link();
struct link* p=NULL;
cout<< "What do you want?"<<endl;
char judge;
cin>>judge;
switch(judge)
{
case '+':
{
heada=add(heada,headb);//加
cout<< "Now I will show you add:"<<endl;
p=heada->next;
while(p)
{
cout << p->coef<< " x^"<<p->exp<<endl;
p=p->next;
}
break;
}
case '-':
{
heada=subtraction(heada,headb);//减
cout<< "Now I will show you subtraction:"<<endl;
p=heada->next;
while(p)
{
cout << p->coef<< " x^"<<p->exp<<endl;
p=p->next;
}
break;
}
case '*' :
{
heada=multiplication(heada,headb);
cout<< "Now I will show you multiplication:"<<endl;
p=heada->next;
while(p)
{
cout << p->coef<< " x^"<<p->exp<<endl;
p=p->next;
}
break;
}
case '/' :
{
//heada=division(heada,headb);
cout<< "Now I will show you multiplication:"<<endl;
p=heada->next;
while(p)
{
cout << p->coef<< " x^"<<p->exp<<endl;
p=p->next;
}
break;
}
default :
cout<< "Wrong input!"<<endl;
}
deleted(heada);
return 0;
}
emm我这个创建有一点憨批,下面给一个例子:
y
0 1
y
10 5
y
1 7
y
2 5
y
1 6
n
y
3 4
y
10 5
y
1 6
y
2 3
y
1 8
n
输入上面的然后就到了switch那步,加减乘除自己选。
上面的例子为
a: 0 x1+10 x5+1 x7+2 x5+1 x6
b: 3 x4+10 x5+1 x6+2 x3+1 x8