谁能想到我居然在测试点3这里出现了段错误?
//0 1 999 1000这出错了
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define OVERFLOW -2 //PAT中没有这个会编译错误
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef struct
{
int coef;
int expn;
}ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*Link,*Position;
typedef struct
{
Link head,tail;
int len;
}LinkList;
typedef LinkList Polynomial;
typedef int Status;
Status InitList(LinkList *L)
{
Link p;
p=(Link)malloc(sizeof(LNode));
if(!p) exit(OVERFLOW);
p->next=NULL;
(*L).head=(*L).tail=p;
(*L).len=0;
return OK;
}
Position GetHead(Polynomial p)
{
return p.head;
}
Status MakeNode(Link *p,ElemType e)
{
(*p)=(Link)malloc(sizeof(LNode));
if(!(*p)) exit(OVERFLOW);
(*p)->data=e;
(*p)->next=NULL;
return OK;
}
void InsFirst(Polynomial *p,Link h,Link s)
{
s->next=h->next;
h->next=s;
if(h==(*p).tail)
(*p).tail=h->next;
(*p).len++;
}
int ListLength(LinkList L)
{
return L.len;
}
ElemType GetCurElem(Link p)
{
return p->data;
}
Status DelFirst(LinkList *L,Link h,Link *q)
{
*q=h->next;
if(*q)
{
h->next=(*q)->next;
if(!h->next)
(*L).tail=h;
(*L).len--;
return OK;
}
return ERROR;
}
Position NextPos(LinkList L,Link p)
{
return p->next;
}
void CreatePolyn(Polynomial *p)
{
InitList(p);
Link h=GetHead(*p);
Link q;
ElemType e;
int n;
scanf("%d",&n);
int i;
for(i=1;i<=n;i++)
{
scanf("%d%d",&e.coef,&e.expn);
if(abs(e.expn)<=1000&&abs(e.coef)<=1000) //abs int fabs double fabsf float
{
MakeNode(&q,e);
InsFirst(p,h,q);
h=h->next;
}
}
}
void PrintPolyn(Polynomial p)
{
int n=ListLength(p);
Link h=GetHead(p);
Link q=h->next;
if(n)
{
int i;
for(i=1;i<=n;i++)
{
if(i==n) printf("%d %d",q->data.coef,q->data.expn);
else printf("%d %d ",q->data.coef,q->data.expn);
q=q->next;
}
}
else printf("%d %d",0,0);
}
int compare(ElemType e1,ElemType e2)
{
if(e1.expn<e2.expn) return -1;
else if(e1.expn>e2.expn) return 1;
else if(e1.expn==e2.expn) return 0;
}
void AddPolyn(Polynomial pa,Polynomial pb,Polynomial *pc)
{
InitList(pc);
Link ha,hb,hc,qa,qb;
ha=GetHead(pa);
hb=GetHead(pb);
hc=GetHead(*pc);
qa=NextPos(pa,ha);
qb=NextPos(pb,hb);
ElemType a,b;
int sum;
Link s;
while(qa&&qb)
{
a=GetCurElem(qa);
b=GetCurElem(qb);
switch(compare(a,b))
{
case 1:
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data=qa->data;
if(s->data.coef==0)
{
ha=qa;
qa=NextPos(pa,ha);
}
else
{
ha=qa;
qa=NextPos(pa,ha);
InsFirst(pc,hc,s);
hc=NextPos(*pc,hc);
}
break;
case 0:
sum=qa->data.coef+qb->data.coef;
if(sum)
{
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data.coef=sum;
s->data.expn=qa->data.expn;
if(s->data.coef)
{
InsFirst(pc,hc,s);
hc=NextPos(*pc,hc);
}
}
ha=qa;
qa=NextPos(pa,ha);
hb=qb;
qb=NextPos(pb,hb);
break;
case -1:
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data=qb->data;
if(s->data.coef==0)
{
hb=qb;
qb=NextPos(pb,hb);
}
else
{
hb=qb;
qb=NextPos(pb,hb);
InsFirst(pc,hc,s);
hc=NextPos(*pc,hc);
}
break;
}
}
while(qa)
{
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data=qa->data;
if(s->data.coef==0)
{
ha=qa;
qa=NextPos(pa,ha);
}
else
{
ha=qa;
qa=NextPos(pa,ha);
InsFirst(pc,hc,s);
hc=NextPos(*pc,hc);
}
}
while(qb)
{
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data=qb->data;
if(s->data.coef==0)
{
hb=qb;
qb=NextPos(pb,hb);
}
else
{
hb=qb;
qb=NextPos(pb,hb);
InsFirst(pc,hc,s);
hc=NextPos(*pc,hc);
}
}
}
void MultiplyPolyn(Polynomial pa,Polynomial pb,Polynomial *pc)
{
InitList(pc);
int a=ListLength(pa);
int b=ListLength(pb);
Link ha,hb,hc,qa,qb,qc;
ha=GetHead(pa);
hb=GetHead(pb);
hc=GetHead(*pc);
qa=NextPos(pa,ha);
qb=NextPos(pb,hb);
while(qa&&qb)
{
int i;
Link s;
for(i=1;i<=b;i++)
{
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data.coef=qa->data.coef*qb->data.coef;
s->data.expn=qa->data.expn+qb->data.expn;
qb=NextPos(pb,qb); //本来在括号内的最下面,由于continue那句移上来了
if(s->data.coef==0) continue; //对输入的是零项的特殊处理
InsFirst(pc,hc,s);
hc=NextPos(*pc,hc);
}
a--;
hc=GetHead(*pc);
while((a--)>0) //刚开始这里是(a--),所以导致在输入0和0时出错,因为这种情况是a原本是0,现在是-1,仍可以进入循环,会出现问题
{
qa=NextPos(pa,qa);
qb=NextPos(pb,hb);
for(i=1;i<=b;i++)
{
s=(Link)malloc(sizeof(LNode));
s->next=NULL;
s->data.coef=(qa->data.coef)*(qb->data.coef);
s->data.expn=(qa->data.expn)+(qb->data.expn);
qb=NextPos(pb,qb); //第一次因为缺少这个地方出错,每次内外qb都需要移动
if(s->data.coef==0) continue; //一定要确保此指令以下没有必要操作否则就会出错
qc=hc;
Link q;
while(qc->next&&(qc->next->data.expn)>(s->data.expn))
qc=qc->next;
if(qc->next&&(qc->next->data.expn==s->data.expn))
{
if((qc->next->data.coef)+(s->data.coef))
{
qc->next->data.coef+=s->data.coef;
}
else
{
DelFirst(pc,qc,&q);
}
}
else if(qc->next&&(qc->next->data.expn<s->data.expn))
{
InsFirst(pc,qc,s);
}
else if(!qc->next)
{
InsFirst(pc,qc,s);
}
}
}
}
}
int main()
{
Polynomial Pa,Pb,Pc,Pd;
CreatePolyn(&Pa);
CreatePolyn(&Pb);
AddPolyn(Pa,Pb,&Pc);
MultiplyPolyn(Pa,Pb,&Pd);
PrintPolyn(Pd);
printf("\n");
PrintPolyn(Pc);
return 0;
}
测试点0:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
Process returned 0 (0x0) execution time : 29.941 s
Press any key to continue.
测试点1:
2 -1000 1000 1000 0
2 1000 1000 -1000 0
-1000000 2000 2000000 1000 -1000000 0
0 0
Process returned 0 (0x0) execution time : 30.476 s
Press any key to continue.
测试点2:
3 0 0 0 0 0 0
1 0 0
0 0
0 0
Process returned 0 (0x0) execution time : 12.448 s
Press any key to continue.
测试点3:
0
1 999 1000
0 0
999 1000
Process returned 0 (0x0) execution time : 15.822 s
Press any key to continue.