题目:
一元多项式运算器
(1)建立多项式。
(2)输出多项式。
(3) +,两个多项式相加,建立并输出和多项式。
(4) -,两个多项式相减,建立并输出差多项式。
扩展:
(5) *,多项式乘法。
(6) ( ),求多项式的值。
题解:
一元多项式运算器的计算中包含加减法,其中一元多项式说明有多个项所以我们可以考虑结构体数组或者链表来存储该数据元素,如果使用结构体数组来存储该数据元素进行计算的话,即要保存其项的个数和各项的系数和指数,在运算加减法时则需要使用多重循环来寻找指数相同的项来进行加减法。但是本篇博客主要简介使用的方法是链表来进行一元多项式的运算。
在创建链表时则需要考虑其链表中所要的值:指数、系数和指向下一个节点的指针。创建链表则需考虑如果输入的指数值相同则循环次数不加继续进行顺换里面的内容则需要使用的到结束语句continue。
结构体的内容如下所示:
typedef struct polynomial
{
float Coef; //系数
int Index; //指数
struct polynomial *next;
} polynomial;
在创建时需考虑是否可以写进链表的代码如下所示:
如果指数相同则不写入链表继续进行数据的输入。
while(cp->next && temp->Index > cp->next->Index)
{
cp = cp->next; //找到链表结点的尾部,且指数是递增的
}
if(cp->next && temp->Index == cp->next->Index){ // 如果已经存在相同指数的多项式,跳出循环
continue;
}
temp->next = cp->next;
cp->next = temp;
若链表输入的数据比下一个数据的指数要小于或等于的时候则跳出while循环进入判断语句if,如果该数据的指数与下一结点的指数相等的时候continue退出不将数据保存在链表之中,若比下一个结点的指数要小的时候则保存在下一个结点之前的位置。
即如下图所示:
相同时则不加入该链表之中即可。
链表创建成功之后我们就可以开始实现其功能,例如一元多项式的加减法,加法与减法的思路大致相同,在此只对一元多项式的加法进行讲述,加法则需要找到指数相同的项相关系数相加即可完成加法的相关操作。创建一个加法的函数,不返回值,使用二级指针指向链表的地址,直接对链表进行修改即可。
void AddPolyn(polynomial **pa, polynomial **pb);
然后声明几个指针,其中两个指针分别指向链表的第一个数据,还有一个指针指向一个链表本身的头指针,然后声明一个循环当两个链表其中有一个空了之后退出该循环,首先判断指数的大小,因为我们创建的两个链表的指数都是升序排列的,在此将两个的链表最终和的结果存储在一个链表之中按照升序的方式排列,所以对两个链表的指数开始进行判断,如果指数小(且没有相同指数)的则首先进入结果链表之中,存入结果链表的指针向后移动一位再次与另一个指针指向的结点指数相比较,如果有相同的指数项存在则将其的指数相加然后存入结果链表之中,随后将指针都向后移动一个结点。然后当其中一个链表结束之后说明再也没有相同的指数出现因此我们可以把剩下的链表内容直接存储在结果链表之中。此加法的操作就结束了,一元多项式的减法操作与其相似只不过是把相同指数相加改为相减即可。
完成上面操作的代码如下所示:
void Add(polynomial **pa, polynomial **pb)
{
polynomial *cpa, *cpb, *p = (*pa);
cpa = (*pa)->next;
cpb = (*pb)->next;
while(cpa && cpb) //对每一项进行比较
{
if(cpa->Index < cpb->Index)
{
p->next = cpa;
p = cpa;
cpa = cpa->next;
}
else if(cpa->Index > cpb->Index)
{
p->next = cpb;
p = cpb;
cpb = cpb->next;
}
else
{
if(cpa->Coef + cpb->Coef == 0)
{
cpa = cpa->next;
cpb = cpb->next;
}
else
{
cpa->Coef += cpb->Coef;
p->next = cpa;
p = cpa;
cpa = cpa->next;
cpb = cpb->next;
}
}
}
if(cpa)
p->next = cpa;
else
p->next = cpb;
free(*pb); //*pb已经为空,释放空间
}
但是减法与其不同的点在于如果减数的链表长度多余被减数的链表长度则不可以直接加入结果链表之中需要将其系数的符号进行改变再加入到结果链表之中。
该操作的代码如下所示:
if(cpb){
p->next = cpb;
while(cpb){
cpb->Coef *= -1; // 改变系数的符号,将减数多项式的系数变为负的
cpb = cpb->next;
}
}
在一元多项式的乘法之中我们利用的函数与其加法函数相同都是使用二级指针,直接对链表本身进行修改,每一项与另一项进行相乘,所以我们才函数开头需创建两个指针,其中一个指针指向链表的头指针,保存链表内容。在乘法进行之前还需要将内容保存在一个函数之中,即将链表内容完全复制在另一个链表中,将此链表重新初始化。然后让此复制的链表与另一链表进行相乘结果保存在复制链表之中,再与之前的链表相加即可得到结果。
运行乘法的代码如下所示:
void Multiply(polynomial **pa, polynomial **pb)
{
polynomial *cpa, *ccpa;
cpa = *pa; //保存着原pa的内容
CreatePolyn(pa, 0); //从新初始化pa为头结点
(*pb) = (*pb)->next;
while(*pb) //只要*pb不为NULL一直进行
{
Copy(&ccpa, cpa); //将后者复制给前者
MultiplyOperate(ccpa, *pb);
Add(pa, &ccpa); //将结果加入到pa中,直到得到最后的结果
(*pb) = (*pb)->next;
}
}
void Copy(polynomial **pa, polynomial *pb)
{
Create(pa, 0);
polynomial *temp, *cpa;
cpa = *pa;
pb = pb->next; // 移动指针指向第一个节点
while(pb)
{
//进行复制操作
temp = (polynomial *)malloc(sizeof(polynomial));
temp->Coef = pb->Coef;
temp->Index = pb->Index;
temp->next = NULL;
cpa->next = temp;
cpa = temp;
pb = pb->next;
}
}
void MultiplyOperate(polynomial *pa, polynomial *pb)
{
pa = pa->next;
while(pa)
{
pa->Coef *= pb->Coef;
pa->Index += pb->Index;
pa = pa->next;
}
}
乘法结束之后,该一元多项式运算器就到这里了。
下面附上该题的完整代码:
#include <iostream>
#include<stdlib.h>
using namespace std;
typedef struct polynomial
{
float Coef; //系数
int Index; //指数
struct polynomial *next;
} polynomial;
//功能函数声明
void CreatePolyn(polynomial **p, int m);
void Add(polynomial **pa, polynomial **pb);
void Subtract(polynomial **pa, polynomial **pb);
void Multiply(polynomial **pa, polynomial **pb);
void Copy(polynomial **pa, polynomial *pb);
void MultiplyOperate(polynomial *pa, polynomial *pb);
void Print(polynomial *p);
int main()
{
polynomial *pa, *pb; //定义两个结构体指针
int n,m; //用来存放多项式的项数
int choose; //选择加减乘
int Flag = 1;
while (1) {
if (Flag == 1) {
cout << "***************** 一元多项式计算器 *****************" << endl;
cout << "请输入第一个多项式的项数->";
cin >> n;
CreatePolyn(&pa, n);
cout << endl;
cout << "请输入第二个多项式的项数->";
cin >> m;
CreatePolyn(&pb, m);
cout << endl;
cout << "********************************" << endl;
cout << "本计算器可以进行的计算方式:" << endl;
cout << "1.相加" << endl;
cout << "2.相减" << endl;
cout << "3.相乘" << endl;
cout << "********************************" << endl;
cout << endl;
cout << "请选择计算方式:";
cin >> choose;
if (choose == 1) {
Add(&pa, &pb); //加法
} else if (choose == 2) {
Subtract(&pa, &pb); //减法
} else{
Multiply(&pa, &pb); //乘法
}
cout << "结果如下: " << endl;
Print(pa);
cout << endl;
}
else {
cout << "**********************************" << endl;
cout << " 谢谢使用本系统! " << endl;
cout << "**********************************" << endl;
return 0;
}
cout << endl;
cout << "**********************************" << endl;
cout << " 是否继续使用? " << endl;
cout << "1.是" << endl;
cout << "2.否" << endl;
cout << "**********************************" << endl;
cin >> Flag;
}
}
void CreatePolyn(polynomial **p, int m)
{
int i, data;
polynomial *cp, *temp;
(*p) = (polynomial *)malloc(sizeof(polynomial));
(*p)->Coef = 0.0;
(*p)->Index = -1;
(*p)->next = NULL;
for(i=1; i<=m; ++i){
cp = *p; //初始位置
temp = (polynomial *)malloc(sizeof(polynomial));
cout << "请输入第" << i << "项的系数: ";
cin >> temp->Coef;
cout << "请输入第" << i << "项的指数: ";
cin >> temp->Index;
while(cp->next && temp->Index > cp->next->Index)
{
cp = cp->next;
}
if(cp->next && temp->Index == cp->next->Index){ // 如果已经存在相同指数的多项式,跳出循环
continue;
}
temp->next = cp->next;
cp->next = temp;
}
}
void Add(polynomial **pa, polynomial **pb)
{
polynomial *cpa, *cpb, *p = (*pa);
cpa = (*pa)->next;
cpb = (*pb)->next;
while(cpa && cpb) //对每一项进行比较
{
if(cpa->Index < cpb->Index)
{
p->next = cpa;
p = cpa;
cpa = cpa->next;
}
else if(cpa->Index > cpb->Index)
{
p->next = cpb;
p = cpb;
cpb = cpb->next;
}
else
{
if(cpa->Coef + cpb->Coef == 0)
{
cpa = cpa->next;
cpb = cpb->next;
}
else
{
cpa->Coef += cpb->Coef;
p->next = cpa;
p = cpa;
cpa = cpa->next;
cpb = cpb->next;
}
}
}
if(cpa)
p->next = cpa;
else
p->next = cpb;
free(*pb); //*pb已经为空,释放空间
}
void Subtract(polynomial **pa, polynomial **pb)
{
polynomial *cpa, *cpb, *p = (*pa);
cpa = (*pa)->next;
cpb = (*pb)->next;
while(cpa && cpb) //对每一项进行比较
{
if(cpa->Index < cpb->Index)
{
p->next = cpa;
p = cpa;
cpa = cpa->next;
}
else if(cpa->Index > cpb->Index)
{
p->next = cpb;
p = cpb;
p->Coef *= -1; // 此时结果为负数,需改变符号
cpb = cpb->next;
}
else // 此时指数相等
{
if(cpa->Coef == cpb->Coef) //如果两项系数相等,删除该节点
{
cpa = cpa->next;
cpb = cpb->next;
}
else
{
cpa->Coef -= cpb->Coef;
p->next = cpa;
p = cpa;
cpa = cpa->next;
cpb = cpb->next;
}
}
}
if(cpa) {
p->next = cpa;
}
if(cpb){
p->next = cpb;
while(cpb){
cpb->Coef *= -1; // 改变系数的符号,将减数多项式的系数变为负的
cpb = cpb->next;
}
}
free(*pb); //*pb已经为空,释放空间
}
void Multiply(polynomial **pa, polynomial **pb)
{
polynomial *cpa, *ccpa;
cpa = *pa; //保存着原pa的内容
CreatePolyn(pa, 0); //从新初始化pa为头结点
(*pb) = (*pb)->next;
while(*pb) //只要*pb不为NULL一直进行
{
Copy(&ccpa, cpa); //将后者复制给前者
MultiplyOperate(ccpa, *pb);
Add(pa, &ccpa); //将结果加入到pa中,直到得到最后的结果
(*pb) = (*pb)->next;
}
}
void Copy(polynomial **pa, polynomial *pb)
{
CreatePolyn(pa, 0);
polynomial *temp, *cpa;
cpa = *pa;
pb = pb->next; // 移动指针指向第一个节点
while(pb)
{
//进行复制操作
temp = (polynomial *)malloc(sizeof(polynomial));
temp->Coef = pb->Coef;
temp->Index = pb->Index;
temp->next = NULL;
cpa->next = temp;
cpa = temp;
pb = pb->next;
}
}
void MultiplyOperate(polynomial *pa, polynomial *pb)
{
pa = pa->next;
while(pa)
{
pa->Coef *= pb->Coef;
pa->Index += pb->Index;
pa = pa->next;
}
}
void Print(polynomial *p)
{
polynomial *temp = p->next;
int a[100000];
double b[100000];
int aid=0,bid=0;
int cnt=0;
cout << "升幂情况: " ;
while(temp){
if(cnt!=0&& temp->Coef > 0)printf("+");
b[bid]= temp->Coef;
a[aid]= temp->Index;
cout << b[bid] << "x^" << a[aid];
aid++;
bid++;
cnt++;
temp = temp->next;
}
if(cnt==0) { //如果是空的输出0
cout << "0";
}
cout << endl;
cout << "降幂情况: ";
int ans=0;
for(int i=aid-1; i>=0; i--){
if(ans!=0&&b[i]>0) {
cout << "+";
}
cout << b[i] << "x^" << a[i];
ans++;
}
}
该题的链表方法讲解就结束了,后续我会补充结构体数组对此题的解法,希望大家多多指教!