一元稀疏多项式计算器
[问题描述]:
设计一个一元稀疏多项式简单计算器。
[基本要求]:
一元稀疏多项式简单计算器的基本功能是:
(1)输出并建立多项式;
(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,...,cn,en,其中n是多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列;
(3)多项式a和b相加,建立多项式a+b;
(4)多项式a和b相减,建立多项式a-b;
[测试数据]
(1)(2x+5x^8-3.1x^11)+(7-5x^8+11x^9)=(-3.1x^11+11x^9+2x+7);
(2)(6x^(-3)-x+4.4x^2-1.2x^9)-(-6x^(-3)+5.4x^2-x^2+7.8x^15)=(-7.8x^15-1.2x^9+12x^(-3)-x);
(3)(x+x^3)+(-x-x^3)=0;
(4)(x+x^2+x^3)+0=x+x^2+x^3;
(由于篇幅原因,只选取了具有代表性的4组测试数据)
[实现提示]
用带表头节点的单链表存储多项式。
一:程序设计流程:
1.建立两个带头节点的单链表A、B。
2.将A、B两个链表连接成一个新链表 C;
3.用冒泡法对C中链表进行排序。
4.把C链表中指数项相同节点合并。
二:程序源代码:
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
typedef struct PolyNode
{
float coef; //系数
int exp; //指数
struct PolyNode *next;
}PolyNode; //用PolyNode定义PolyNode的结构体变量。
typedef PolyNode *Polynomial; //是将*Polynomial定义为struct PolyNode类型,即Polynomial被定义为一个类型名。这样就可以用Polynomial来定义说明新的变量了
Polynomial CreateList()
{
float co;
int ex;
Polynomial head,p,l;
head=(Polynomial)malloc(sizeof(PolyNode));
p=head;
scanf("%f%d",&p->coef,&p->exp); //设置头结点,并且设置第一个节点,为了保证表不为空
if(head->coef==0&&head->exp==0)
{ //如果头结点数据元素均为0,则为单节点链表
head->next=NULL;
}
else
{
p->next=(Polynomial)malloc(sizeof(PolyNode));
p=p->next;
while(1)
{
scanf("%f%d",&co,&ex);
if(co==0&&ex==0)
break; // 系数=0并且指数=0 代表结束输出
{
p->coef=co;
p->exp =ex;
l=p;
p->next =(Polynomial)malloc(sizeof(PolyNode));
p=p->next;
}
}
l->next = NULL;
}
return head;
}
void Sortlist(Polynomial L) // 用冒泡法对链表L中的节点按指数降序排列。
{
Polynomial a,b;
float temp_co; //设置中间变量来交换链表元素的值;
int temp_ex;
b =L;
a =L;
for(a;a!=NULL;a=a->next)
{
b= L ;
for(b;b->next!=NULL;b=b->next)
{
if(b->exp<b->next->exp)
{
temp_co=b->coef;
temp_ex=b->exp;
b->coef=b->next->coef;
b->exp =b->next->exp;
b->next->coef =temp_co;
b->next->exp =temp_ex;
}
}
}
return;
}
void Display(Polynomial p)
{
Polynomial Pointer;
Pointer =p;
do
{
printf("%.2fx^%d ",Pointer->coef,Pointer->exp);
Pointer=Pointer->next;
}
while(Pointer!=NULL);
}
Polynomial LinkList(Polynomial A,Polynomial B,int n) //链接链表A B,在这里设定B的头指针为连接后的头指针 n=1表示加法,n=2表示减法;
{
Polynomial tail_b,C,op_pointer; // op_pointer 用来取反链表B cof 的数值。
tail_b =B;
op_pointer =B;
for(op_pointer;op_pointer!=NULL;op_pointer=op_pointer->next)
{
if(n==2)
{
op_pointer->coef = -op_pointer->coef;
//printf("%.2f %d\n",op_pointer->coef,op_pointer->exp);
}
};
for(tail_b;tail_b->next!=NULL;tail_b=tail_b->next); // 连接 B A 链表,以B链表头为合并后的表头
tail_b->next=A;
C=B;
Sortlist(C);
return C;
}
void MergeList(Polynomial C)
{ // 合并C中exp数值相同的节点.
Polynomial C1,C2;
C1=C;
C2=C1->next;
while(C2!=NULL)
{
if(C1->exp==C1->next->exp)
{
C1->coef=C1->next->coef+C1->coef;
C1->next=C1->next->next;
free(C2);
C2=C1->next;
}
else
{
C1=C1->next;
C2=C2->next;
}
}
}
int main()
{
Polynomial A,B,Com;
int s;
printf("\n请输入链表A的数据为:X的系数,X的指数。两个数据以空格分开。\n:输入0 0表示输入结束。\n");
A=CreateList();
Display(A);
printf("\n\n\n请输入链表B的数据为: X的系数,X的指数。两个数据以空格分开。\n:输入0 0表示输入结束。\n");
B=CreateList();
Display(B);
printf("请选择加法还是减法\n");
printf("输入1代表加法\n");
printf("输入2代表减法\n");
scanf("%d",&s);
if(s==1||s==2){
Com=LinkList(A,B,s);
MergeList(Com);
Display(Com);
}
else
{
printf("输入了非法字符\n");
}
}
三、测试数据
1.(2x+5x^8-3.1x^11)+(7-5x^8+11x^9)=(-3.1x^11+11x^9+2x+7);
2.(6x^(-3)-x+4.4x^2-1.2x^9)-(-6x^(-3)+5.4x^2-x^2+7.8x^15)=(-7.8x^15-1.2x^9+12x^(-3)-x);
3.(x+x^3)+(-x-x^3)=0;
4.(x+x^2+x^3)+0=x+x^2+x^3;