1、任务描述
设有一元多项式Am(x)和Bn(X),编程实现多项式Am(x)和Bn(x)的加法、减法和乘法运算。其中多项式描述为:
Am(x)=A0+A1x1+A2x2+A3x3+….+Amxm;
Bn(x)=B0+B1x1+B2x2+B3x3+….+Bnxn。
2、主要数据类型与变量
使用到的头文件
#include <iostream>
#include <stdlib.h> //C++的基本函数库
#include <stdio.h>
#include <ctime> //随机时间生成测试数据使用
using namespace std;
多项式节点定义
typedef struct PolyNode *Polynomial; //该节点指针类型
struct PolyNode { //多项式的节点类型
int coef; //整形系数
int expon; //整形指数
Polynomial link; //下一个节点
};
3、算法或程序模块
函数接口的定义
/**函数接口定义**/
Polynomial ReadPoly(); //读入多项式
void Attach( int c, int e, Polynomial *pRear ); //连接节点
Polynomial Add( Polynomial P1, Polynomial P2 ); //加法计算
Polynomial Mult( Polynomial P1, Polynomial P2 ); //乘法计算
Polynomial CreatePolynomial();//创建节点类型的空间,初始化用
Polynomial ReadSubPoly();//减法计算
void FallPrintPoly( Polynomial P );//按指数降序输出多项式
void UpPrintPoly( Polynomial P );//按指数升序序输出多项式
void reverseList(Polynomial P); //翻转无头链表 ,不同顺序输出使用
Polynomial ReadPolyRandom(); //随机生成测试数据
核心函数解释
该函数重复使用率极高,所以用一个函数来构造,方便后面的程序直接调用返回一个有空间的多项式节点
/**
* 创建节点并分配内存空间
* @return Polynomial
*/
Polynomial CreatePolynomial(){
Polynomial P;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
return P;
}
}/**
* 随机生成多项式
* @return 返回一个Polynomial类型的链表
*/
Polynomial ReadPolyRandom()
{
time_t t1;
srand((unsigned int) time(&t1)); //通过时间来确定随机数
Polynomial P,Rear,t; //P是要返回的多项式,Rear是尾巴用来连接新节点,t是辅助
int c,e=99,N,i=1,random=14;
N = (rand() % (9))+ 1;
P = CreatePolynomial(); //为P分配空间
Rear = P;
while ( N-- ) {
c=(rand() % (9))+ 1; //通过rand随机函数根据时间不同生成测试数据
random -= 2;
e = random;
Attach(c, e, &Rear);/* 将当前项插入多项式尾部 */
}
t=P;P=P->link;free(t); //删除临时生成的头结点
cout<<"---生成的多项式为---"<<endl;
FallPrintPoly(P);
return P;
}
翻转无头链表,为了逆序输出,这里要注意翻转链表本身,还不是返回一个链表,所以要传多项式地址作为参数
/**
* 翻转链表
* @param *P 为指针,因为要修改内存中此链表的顺序,所以要传引用,而不是传值
*/
void reverseList(Polynomial *P) {
//....省略不关键的代码
Polynomial help = CreatePolynomial(); //无头链表可以在头的前面增加一个假头(辅助头)来创建有头链表。
help->link = *P;
Polynomial cur = help->link; //当前遍历到的节点
Polynomial next = cur->link; //当前的下一个节点
Polynomial reversP = CreatePolynomial();//新链表的头
while (cur) {
next = cur->link; //当前的下一个节点
//表示链表P的结点翻转到链表Help上面的核心语句
cur->link = reversP->link;
reversP->link = cur;
cur = next; //当前节点后移
}
*P = reversP->link; //指向已翻转链表的第一个数据
}
加法:两个多项式从头同时比较,如果指数相等,就相加系数,且系数不为零就加入到要返回的链表P上,两个节点同时后移。
如果指数大的,就插入链表,且该大的节点后移一位。否则相反节点进行同样操作。
Polynomial Add( Polynomial P1, Polynomial P2 ){
Polynomial t1=P1,t2=P2,Rear,P;
//Rear 便于增加新的节点,P是返回的结果
int sum; //计算节点系数的和
P = CreatePolynomial();
Rear = P;
while(t1 && t2){ //当两个多项式都不空
if(t1->expon == t2->expon){ //如果指数相等
sum=t1->coef+t2->coef;
if(sum!=0){ //如果相加结果不为0
Attach(sum,t1->expon,&Rear);//连接到P的尾巴上
}
t1=t1->link; t2=t2->link;
} else if(t1->expon > t2->expon){ //指数大的方前面
Attach(t1->coef,t1->expon,&Rear);
t1=t1->link;
} else{ //指数小的方后面
Attach(t2->coef,t2->expon,&Rear);
t2=t2->link;
}
}
while(t1){ //如果多项式P1还有节点,就转移到结果的尾巴上
Attach(t1->coef,t1->expon,&Rear);
t1=t1->link;
}
while(t2){//如果多项式P2还有节点,就转移到结果的尾巴上
Attach(t2->coef,t2->expon,&Rear);
t2=t2->link;
}
return P->link; //返回多项式的第一个非零项
}
减法:因为有了加法的定义,所以只需要在读入的时候处理一下节点系数的符号就可完成减法的功能。
/**
* 减法读入,为了实现减法
* @return 返回多项式的减数
*/
Polynomial ReadSubPoly()
{
Polynomial P,Rear,t;
int c,e,N,i=1;
cout<<"请输入多项式的长度"<<endl;
scanf("%d", &N);
P = CreatePolynomial();//分配内存空间
Rear = P;
while ( N-- ) {
printf("请输入多项式%d的节点\n",i++);
scanf("%d %d", &c, &e);
Attach(-c, e, &Rear);//把正节点的系数改为负数,就是负节点
}
t=P;P=P->link;free(t); //删除临时生成的头结点
return P;
}
乘法:首先要在循环外初十结果多项式
转换为加法计算,指数相加,系数相乘,然后将结果通过Attach函数连接到要返回链表的尾部。
将P1当前项(c1i,e1i)乘P2当前项(c2i,e2i),并插入到结果多项式
因为有点长,展示这个是核心的代码
while (t1){
t2 = P2; Rear=P;
while (t2){
e = t1->expon + t2->expon;
c = t1->coef * t2->coef;
//如果当前节点相乘结果的指数小于链表中的指数,就继续遍历
while (Rear->link && Rear->link->expon > e){
Rear = Rear->link;
}
//判断两个指数相同时,系数不为0的话,就相加,否则链表往后移动
if(Rear->link && Rear->link->expon == e){
int sum = Rear->link->coef+c;
if (sum!=0){
Rear->link->coef +=c;
} else{
Rear->link = Rear->link->link; //指针移动
}
} else{ //如果e大于 当前的e,那就插在头上
t = CreatePolynomial(); //创建一个临时节点存放当前遍历的结果
t->coef = c; t->expon = e;
t->link = Rear->link; //通过交换方式存入链表的头部
Rear ->link = t;
}
t2 = t2->link;
}
t1 = t1->link;
}
主程序main函数的定义
int main()
{
while (1){
cout<<"**************************欢迎使用多项式计算器*********************************"<<endl;
cout<<"**********请输入你所需要的功能*********"<<endl;
cout<<"0-----退出系统-----"<<endl;
cout<<"1-----多项式相加-----"<<endl;
cout<<"2-----多项式相乘-----"<<endl;
cout<<"3-----多项式相减-----"<<endl;
cout<<"4-----随机生成多项式-----"<<endl;
cout<<"************************************"<<endl;
int input;
cin>>input;
Polynomial P1, P2, res;
switch (input){
case 0:
return 0;
case 1:
cout<<"************请输入第一个多项式************"<<endl;
P1 = ReadPoly();
cout<<"************请输入第二个多项式************"<<endl;
P2 = ReadPoly();
res = Add( P1, P2 );
cout<<"************两个多项式相加结果如下************"<<endl;
FallPrintPoly(res);
UpPrintPoly(res);
break;
case 2:
cout<<"************请输入第一个多项式************"<<endl;
P1 = ReadPoly();
cout<<"************请输入第二个多项式************"<<endl;
P2 = ReadPoly();
res = Mult( P1, P2 );
cout<<"************两个多项式相乘结果如下************"<<endl;
FallPrintPoly(res);
UpPrintPoly( res );
break;
case 3:
cout<<"************请输入第一个多项式************"<<endl;
P1 = ReadPoly();
cout<<"************请输入第二个多项式************"<<endl;
P2 = ReadSubPoly();
res = Add( P1, P2 );
cout<<"************两个多项式相减结果如下************"<<endl;
FallPrintPoly( res );
UpPrintPoly( res );
break;
case 4:
cout<<"************第一个多项式为************"<<endl;
P1 = ReadPolyRandom();
cout<<"************请输入第二个多项式************"<<endl;
P2 =ReadPolyRandom();
res = Add( P1, P2 );
cout<<"************两个多项式相加结果如下************"<<endl;
FallPrintPoly( res );
UpPrintPoly( res );
cout<<"************两个多项式相乘结果如下************"<<endl;
res = Mult( P1, P2 );
FallPrintPoly( res );
UpPrintPoly( res );
break;
}
}
}
三、测试
1、方案
主程序进来的界面
通过选择4通过随机函数输入多项式,进行运算
A = 9 12,3 10,8 8
B = 8 12,6 10,8 8,9 6,4 4,1 2,1 0
通过选择3手动输入生成多项式,相减
3
A = 4 6 ,7 5, 4 2
2
B = 7 6, 4 4
2、结果
结果正确
多项式相减:
答案正确