数据结构实验——用链表实现简单的多项式乘法
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本人计算机小菜鸟,写的程序比较垃圾,仅供参考,也是作为自己成长的一份记录,欢迎大家批评指正!
提示:以下是本篇文章正文内容,下面案例可供参考
一、实验要求
实验目的:
设计一个一元稀疏多项式简单计算器。
一元稀疏多项式简单计算器的基本功能是:
(1)输入并建立多项式。;
(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,…,cn,en,其中n是多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列。
(3)多项式a与多项式b相乘,建立多项式。
二、实验内容和实验步骤:
1.需求分析
代码如下(示例):
(1)输入的形式为第一行输入多项式的项数,第二行输入多项式的内容,内容格式为系数+“ ”+指数的形式,有多少项数就输入多少系数和指数;输入值的范围为整数和浮点数。整数作为指数,浮点数作为系数。
(2)输出的形式为一行表示多项式的数值,例:
请输入多项式的项数:3
请输入数据:1 2 3 4 5 6
排序之后为:5 * x^6 + 3 * x^4 + 1 * x^2
(3)程序所能实现的功能为简单的多项式合并和多项式按照指数进行降序排序,并能实现多项式的乘法。
2.概要设计
代码如下(示例):
(1)考虑到在合并同类项和多项式乘法时需要进行数据的筛检和删除,所以在进行数据结构定义是运用链表进行设计和应用。
struct point{
float c; //c 系数
int e; //e 指数
struct point *next;
};
(2)主程序以及各程序模块之间的关系:主程序负责建立链表和调用各模块程序。在主函数中首先建立多项式,然后分别调用输入函数、排序函数和合并函数将该多项式输入、排序、合并之后进行输出。然后进行多项式的乘法,首先建立两个多项式,然后直接进行多项式的乘法。然后调用排序、合并和输出函数将相乘之后的函数进行输出。
3.代码设计
(1)首先给出我的代码(c++)
#include <iostream>
#include <cstdlib>
using namespace std;
struct point{
float c; //c 系数
int e; //e 指数
struct point *next;
};
void change(struct point *p,struct point *q){
float ct;
int et;
ct = p->c;
p->c = q->c;
q->c = ct;
et = p->e;
p->e = q->e;
q->e = et;
}
//输入函数
void input(struct point *p,struct point *head){
p = head;
int n;
cout<<"请输入多项式的项数:";
cin>>n;
cout<<"请输入数据:";
for (int i = 0; i < n; i++) {
struct point *s = (struct point *)malloc(sizeof(struct point));
cin>>s->c>>s->e;
p->next = s;
s->next = NULL;
p = s;
}
}
//排序函数
void sort(struct point *p,struct point *head){
p = head;
struct point *p1 = NULL,*p2 = NULL,*p3 = NULL;
p1 = p->next;
p2 = p->next;
while (p1 != p3) {
while ((p1->next) != p3) {
if ((p1->e) < (p1->next->e)) {
change(p1, p1->next);
}
p1 = p1->next;
}
p3 = p1;
p1 = p->next;
}
}
//合并同类项函数
void merge1(struct point *p,struct point *head){
p = head;
for (struct point *q = p->next; q != NULL&&q->next != NULL;){
if ((q->e) == (q->next->e)) {
q->c += q->next->c;
q->next = q->next->next;
}else q = q->next;
}
}
//输出函数
void output(struct point *p,struct point *head){
cout<<"排序之后为:";
p = head;
for (struct point *i = p->next; i != NULL;) {
if(i->c != 0){
cout<<i->c<<" * "<<"x^"<<i->e<<" ";
if (i->next != NULL) {
cout<<"+ ";
}
}
i = i->next;
}
cout<<endl;
}
int main() {
struct point * head = (struct point *)malloc(sizeof(struct point));
head->next = NULL;
struct point * p = nullptr;
input(p, head);
sort(p, head);
merge1(p, head);
output(p, head);
//多项式乘法
cout<<"-----下面进行多项式的乘法-----"<<endl<<"请输入第一个多项式:"<<endl;
struct point * head1 = (struct point *)malloc(sizeof(struct point));
struct point * newp1 = nullptr;
input(newp1, head1);
sort(newp1, head1);
merge1(newp1, head1);
output(newp1, head1);
cout<<"请输入第二个多项式:"<<endl;
struct point * head2 = (struct point *)malloc(sizeof(struct point));
struct point * newp2 = nullptr;
input(newp2, head2);
sort(newp2, head2);
merge1(newp2, head2);
output(newp2, head2);
newp1 = head1;
newp2 = head2;
struct point * Mhead = (struct point *)malloc(sizeof(struct point));
struct point * Mp = nullptr;
Mp = Mhead;
while (newp1->next != NULL) {
while (newp2->next != NULL) {
struct point *p = (struct point *)malloc(sizeof(struct point));
p->c = newp1->next->c * newp2->next->c;
p->e = newp1->next->e + newp2->next->e;
Mp->next = p;
p->next = NULL;
Mp = p;
newp2 = newp2->next;
}
newp1 = newp1->next;
newp2 = head2;
}
sort(Mp, Mhead);
merge1(Mp, Mhead);
cout<<"相乘之后得到";
output(Mp, Mhead);
return 0;
}
(2)分析主要函数
//输入函数
void input(struct point *p,struct point *head){
p = head;
int n;
cout<<"请输入多项式的项数:";
cin>>n;
cout<<"请输入数据:";
for (int i = 0; i < n; i++) {
struct point *s = (struct point *)malloc(sizeof(struct point));
cin>>s->c>>s->e;
p->next = s;
s->next = NULL;
p = s;
}
}
输入函数用的是最基本的输入方法,用另外的指针p指向定义的链表head,然后利用for循环进行链表节点内容的输入,每次输入c和e之后指针后移指向下一个结点。在这里利用malloc函数开辟一个新的结点s,将内容c和e输入到这个结点s中,然后将s结点链接在p的后面,然后将p后移一个结点。
//排序函数
void sort(struct point *p,struct point *head){
p = head;
struct point *p1 = NULL,*p2 = NULL;
p1 = p->next;
while (p1 != p2) {
while ((p1->next) != p2) {
if ((p1->e) < (p1->next->e)) {
change(p1, p1->next);
}
p1 = p1->next;
}
p2 = p1;
p1 = p->next;
}
}
因为要进行多项式按照指数的降幂排列,排序函数就实现这个功能,将链表输入,要实现函数的降幂排序。排序时,创建两个链表指针,一个指向现在的,一个指向下一个结点,当两个结点也就是e不是按照降幂排序的时,则将两个结点的内容进行交换。
//合并同类项函数
void merge1(struct point *p,struct point *head){
p = head;
for (struct point *q = p->next; q != NULL&&q->next != NULL;){
if ((q->e) == (q->next->e)) {
q->c += q->next->c;
q->next = q->next->next;
free(q->next);
}else q = q->next;
}
}
合并同类项函数是建立在已经排好序的情况下的,定义一个指针之后进行同类项的合并,用这一个指针进行遍历,如果这个指针指向的内容中的e和下一个结点中的e一样,则将两个结点中的c加到第一个结点上,然后用q->next = q->next->next跳过下个结点,然后将q->next 结点free掉即可,每次遍历往后移一位。
//输出函数
void output(struct point *p,struct point *head){
cout<<"排序之后为:";
p = head;
for (struct point *i = p->next; i != NULL;) {
if(i->c != 0){
cout<<i->c<<" * "<<"x^"<<i->e<<" ";
if (i->next != NULL) {
cout<<"+ ";
}
}
i = i->next;
}
cout<<endl;
}
输出函数就非常简单啦,只需要考虑到在合并式有c = 0的情况,此类结点不需要输出,所以在输出时加一个if判断条件如果c = 0的话将该结点跳过即可。
//多项式乘法
struct point * Mhead = (struct point *)malloc(sizeof(struct point));
struct point * Mp = nullptr;
Mp = Mhead;
while (newp1->next != NULL) {
while (newp2->next != NULL) {
struct point *p = (struct point *)malloc(sizeof(struct point));
p->c = newp1->next->c * newp2->next->c;
p->e = newp1->next->e + newp2->next->e;
Mp->next = p;
p->next = NULL;
Mp = p;
newp2 = newp2->next;
}
newp1 = newp1->next;
newp2 = head2;
}
然后进行多项式的乘法,这也是这个地方复杂的地方,多项式的乘法所要做的就是将第一个链表中的每一项都与第二个链表进行相乘(即系数相乘,指数相加),然后将乘完之后的数据存在新的链表Mhead中,此时需要两个循环,第一重循环需要遍历第一个链表所有的数,然后第二个循环需要遍历第二个链表中所有的数,最后将答案输出即可。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了怎么用单链表实现多项式的乘法,本人比较菜,欢迎大家批评指正!