中国大学MOOC-陈越、何钦铭-数据结构 一元多项式的乘法与加法运算
2015-09-27 23:42
597 查看
哈哈哈,写出了困扰自己一个多星期的题目,心情真是好的不得了.顿时,自己内心生出了一种自豪感,这种解决了”难题”的感觉真是太美妙了.
回到题目来:
题目内容:
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出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
分析:
对于这道题目,难点在于多项式的加法和乘法操作,涉及到链表的插入,排序和删除操作.
对于加法操作,因为传入的多项式都是按指数排列的,所以加法操作基本上是按个从两个多项式从头到尾进行运算,把两个子项的结果插入到一个新的多项式的尾部.所以对此我写了附加到尾部的函数
对于乘法,我首先先是计算了第一个多项式第一项挨个与第二个多项式各项的乘积,得到了一个基本的多项式.这可以用到加法操作的那个函数.
接下来就是第一个多项式剩下的项与第二个多项式的各项相乘,并插入刚才的那个链表中,所以到此我用写了一个插入的函数
接下来就是多项式的输入,输出的函数了
值得注意的是零多项式的处理
代码如下:`#include
using namespace std;
int Num1,Num2;//记录多项式的非零项个数
struct Poly{//多项式的项的表示
int coe;//多项式的系数
int exp;//多项式的系数
Poly *next;
};
void Input(Poly * &head, int num){//输入函数
Poly *s, *p;
p = head;//指向头结点,方便插入
int i = 1;//计数作用
s = new Poly;
while (i<=num){//挨个输入
cin >> s->coe;
cin >> s->exp;
if (head == NULL){ head = s; }
else { p->next = s; }
p =s;
s = new Poly;
i++;
}
p->next = NULL;
delete s;}
void output(Poly * &poly){//输出函数,按题目要求的格式输出
while (poly->next){
cout << poly->coe << ” ” << poly->exp << ” “;
poly = poly->next;
}
cout << poly->coe << ” ” << poly->exp << endl;
}
int Judge(Poly *head1, Poly *head2){//对两个指针指向的多项式的系数进行判断,并返回值
if (head1->exp > head2->exp){
return 1;}
if (head1->exp < head2->exp){
return -1;}
if (head1->exp == head2->exp){
return 0; }
}
void Append(Poly * &poly,int coe,int exp){//附加到尾部的函数
Poly *p;//p是辅助插入的指针
Poly *s; s = new Poly; s->coe = coe; s->exp = exp; s->next = NULL;
if (poly->coe == 0){ poly = s; return; }
else{
p = poly;
while (p->next){ p = p->next; }//遍历找到链表的尾部
p->next = s;//插入
return;
}
}
void Insert(Poly * &poly, int coe,int exp){//插入的函数
Poly *temp; temp = new Poly; temp->coe = coe; temp->exp=exp; temp->next = NULL;
Poly *p, *q;//p是辅助插入的指针,q是p的前驱指针
q = poly; p = poly->next;//头结点的指数最大,所以不用考虑头结点
while (p){
if (p->exp > temp->exp){ q = p; p = p->next; }
else{
if (p->exp < temp->exp){//p指向的节点的指数小于temp的指数,则要把temp插入到p之前
temp->next = p;//把temp指向p
q->next = temp;//把temp插入进来
return;
}
else
if (p->exp == temp->exp){//p指向的节点的指数与temp的指数相等
if (p->coe + temp->coe != 0){//检查系数相加是否为零
p->coe += temp->coe;//系数不为零,则把系数相加
return;
}
else
if (p->coe + temp->coe == 0){//系数相加为零
Poly *d = p;
q->next = p->next;
delete d;
return;
}}}}
if (!p){ q->next = temp; return; }//如果遍历已有的节点都找不到合适的位置插入,说明该节点只能插入节点尾部
}
void add(Poly * &poly1,Poly * &poly2, Poly *add_poly){//进行加法运算
Poly *head1, *head2;
head1 = poly1;
head2 = poly2;
int j;
while (head1&&head2){
j = Judge(head1, head2);//判断项的指数大小
switch (j){
case 1:Append(add_poly, head1->coe,head1->exp);//head1的指数较大
head1 = head1->next;
break;
case -1:Append(add_poly, head2->coe,head2->exp);//head2的指数较大
head2 = head2->next;
break;
case 0:if (head1->coe + head2->coe != 0){//两者指数相等,并且系数相加不为零
Append(add_poly, head1->coe+head2->coe,head1->exp);}
head1 = head1->next;
head2 = head2->next;
break;
}
}
while (head1){//head1不为空时
Append(add_poly, head1->coe,head1->exp);
head1 = head1->next;
}
while (head2){//head2不为空时
Append(add_poly, head2->coe,head2->exp);
head2 = head2->next;
}
}
void multiply(Poly * &poly1,Poly * &poly2,Poly *multiply_poly){
Poly *head1, *head2;//分别指向Poly1,Poly2
head1 = poly1;
head2 = poly2;
}
int main()
{ Poly *poly1, *poly2;
Poly *add_poly, *multiply_poly;
Poly *o;
poly1 =NULL;
poly2 =NULL;
add_poly = new Poly; add_poly->coe = 0; add_poly->exp = 0;
multiply_poly = new Poly; multiply_poly->coe = 0; multiply_poly->exp = 0;
cin >> Num1;
if (Num1)
{
Input(poly1, Num1);
}
cin >> Num2;
if (Num2)
{
Input(poly2, Num2);
}
if (Num1&&Num2){//两者都不为零
multiply(poly1, poly2, multiply_poly);
add(poly1, poly2, add_poly);
}
if (!Num1){//Num1为零
cout << “0 0” << endl;
output(poly2);
}
if (!Num2){//Num2为零
cout << “0 0” << endl;
output(poly1);
}
if (!Num1&&!Num2){//两者都为零
cout << “0 0” << endl << “0 0”;
}
}`
思考:老师要求用链表实现,可惜自己一开始并不是很会使用链表,乱搞一通,结果肯定都没出来.过了几天后,回去看视频,明白了要给不同的功能抽象在一起,写成一个函数.更明白了,对于链表的操作,如插入,删除等,最好写成一个函数,再传递参数进去.对于自己一开始把所有链表的插入,删除操作都写在函数里面的做法要完全摒弃.
不过,我还是没能真正理解指针的使用,这方面还的加强.
回到题目来:
题目内容:
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出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
分析:
对于这道题目,难点在于多项式的加法和乘法操作,涉及到链表的插入,排序和删除操作.
对于加法操作,因为传入的多项式都是按指数排列的,所以加法操作基本上是按个从两个多项式从头到尾进行运算,把两个子项的结果插入到一个新的多项式的尾部.所以对此我写了附加到尾部的函数
对于乘法,我首先先是计算了第一个多项式第一项挨个与第二个多项式各项的乘积,得到了一个基本的多项式.这可以用到加法操作的那个函数.
接下来就是第一个多项式剩下的项与第二个多项式的各项相乘,并插入刚才的那个链表中,所以到此我用写了一个插入的函数
接下来就是多项式的输入,输出的函数了
值得注意的是零多项式的处理
代码如下:`#include
using namespace std;
int Num1,Num2;//记录多项式的非零项个数
struct Poly{//多项式的项的表示
int coe;//多项式的系数
int exp;//多项式的系数
Poly *next;
};
void Input(Poly * &head, int num){//输入函数
Poly *s, *p;
p = head;//指向头结点,方便插入
int i = 1;//计数作用
s = new Poly;
while (i<=num){//挨个输入
cin >> s->coe;
cin >> s->exp;
if (head == NULL){ head = s; }
else { p->next = s; }
p =s;
s = new Poly;
i++;
}
p->next = NULL;
delete s;}
void output(Poly * &poly){//输出函数,按题目要求的格式输出
while (poly->next){
cout << poly->coe << ” ” << poly->exp << ” “;
poly = poly->next;
}
cout << poly->coe << ” ” << poly->exp << endl;
}
int Judge(Poly *head1, Poly *head2){//对两个指针指向的多项式的系数进行判断,并返回值
if (head1->exp > head2->exp){
return 1;}
if (head1->exp < head2->exp){
return -1;}
if (head1->exp == head2->exp){
return 0; }
}
void Append(Poly * &poly,int coe,int exp){//附加到尾部的函数
Poly *p;//p是辅助插入的指针
Poly *s; s = new Poly; s->coe = coe; s->exp = exp; s->next = NULL;
if (poly->coe == 0){ poly = s; return; }
else{
p = poly;
while (p->next){ p = p->next; }//遍历找到链表的尾部
p->next = s;//插入
return;
}
}
void Insert(Poly * &poly, int coe,int exp){//插入的函数
Poly *temp; temp = new Poly; temp->coe = coe; temp->exp=exp; temp->next = NULL;
Poly *p, *q;//p是辅助插入的指针,q是p的前驱指针
q = poly; p = poly->next;//头结点的指数最大,所以不用考虑头结点
while (p){
if (p->exp > temp->exp){ q = p; p = p->next; }
else{
if (p->exp < temp->exp){//p指向的节点的指数小于temp的指数,则要把temp插入到p之前
temp->next = p;//把temp指向p
q->next = temp;//把temp插入进来
return;
}
else
if (p->exp == temp->exp){//p指向的节点的指数与temp的指数相等
if (p->coe + temp->coe != 0){//检查系数相加是否为零
p->coe += temp->coe;//系数不为零,则把系数相加
return;
}
else
if (p->coe + temp->coe == 0){//系数相加为零
Poly *d = p;
q->next = p->next;
delete d;
return;
}}}}
if (!p){ q->next = temp; return; }//如果遍历已有的节点都找不到合适的位置插入,说明该节点只能插入节点尾部
}
void add(Poly * &poly1,Poly * &poly2, Poly *add_poly){//进行加法运算
Poly *head1, *head2;
head1 = poly1;
head2 = poly2;
int j;
while (head1&&head2){
j = Judge(head1, head2);//判断项的指数大小
switch (j){
case 1:Append(add_poly, head1->coe,head1->exp);//head1的指数较大
head1 = head1->next;
break;
case -1:Append(add_poly, head2->coe,head2->exp);//head2的指数较大
head2 = head2->next;
break;
case 0:if (head1->coe + head2->coe != 0){//两者指数相等,并且系数相加不为零
Append(add_poly, head1->coe+head2->coe,head1->exp);}
head1 = head1->next;
head2 = head2->next;
break;
}
}
while (head1){//head1不为空时
Append(add_poly, head1->coe,head1->exp);
head1 = head1->next;
}
while (head2){//head2不为空时
Append(add_poly, head2->coe,head2->exp);
head2 = head2->next;
}
if (add_poly->coe){ //输出加法运算的结果 output(add_poly); } else { cout << "0 0"; }
}
void multiply(Poly * &poly1,Poly * &poly2,Poly *multiply_poly){
Poly *head1, *head2;//分别指向Poly1,Poly2
head1 = poly1;
head2 = poly2;
while (head2){ Append(multiply_poly, head1->coe*head2->coe, head1->exp + head2->exp);//先生成一个基本的多项式 head2 = head2->next; } head1 = head1->next; while (head1){//对剩下的多项式进行运算 head2 = poly2; while (head2){ Insert(multiply_poly, head1->coe*head2->coe, head1->exp + head2->exp); head2 = head2->next; } head1 = head1->next; } output(multiply_poly);
}
int main()
{ Poly *poly1, *poly2;
Poly *add_poly, *multiply_poly;
Poly *o;
poly1 =NULL;
poly2 =NULL;
add_poly = new Poly; add_poly->coe = 0; add_poly->exp = 0;
multiply_poly = new Poly; multiply_poly->coe = 0; multiply_poly->exp = 0;
cin >> Num1;
if (Num1)
{
Input(poly1, Num1);
}
cin >> Num2;
if (Num2)
{
Input(poly2, Num2);
}
if (Num1&&Num2){//两者都不为零
multiply(poly1, poly2, multiply_poly);
add(poly1, poly2, add_poly);
}
if (!Num1){//Num1为零
cout << “0 0” << endl;
output(poly2);
}
if (!Num2){//Num2为零
cout << “0 0” << endl;
output(poly1);
}
if (!Num1&&!Num2){//两者都为零
cout << “0 0” << endl << “0 0”;
}
}`
思考:老师要求用链表实现,可惜自己一开始并不是很会使用链表,乱搞一通,结果肯定都没出来.过了几天后,回去看视频,明白了要给不同的功能抽象在一起,写成一个函数.更明白了,对于链表的操作,如插入,删除等,最好写成一个函数,再传递参数进去.对于自己一开始把所有链表的插入,删除操作都写在函数里面的做法要完全摒弃.
不过,我还是没能真正理解指针的使用,这方面还的加强.
相关文章推荐
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构揭秘一
- 数据结构之Treap详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)
- java数据结构和算法学习之汉诺塔示例
- Java数据结构及算法实例:三角数字
- Java数据结构之简单链表的定义与实现方法示例
- 数据结构之AVL树详解
- qqwry.dat的数据结构图文解释第1/2页
- JavaScript中数据结构与算法(五):经典KMP算法