数据结构实验:基于链表的多项式乘法

该文描述了一个C++编程任务,涉及从字符文件读取两个多项式的系数和指数,使用链表存储,实现多项式的乘法运算,并将结果输出到另一个文件。算法基于将乘法转化为加法,利用单向链表按指数升序连接的结构。程序使用C++的cin和cout进行输入输出,以及VisualStudio2022作为开发环境。
摘要由CSDN通过智能技术生成

实验内容及要求:

从字符文件输入两个多项式的非零系数及对应的指数,建立多项式的链式存储结构,计算这两个多项式的乘积,输出乘积多项式的全部非零系数及对应的指数到另一字符文件中。

要求输入输出字符文件中的数据格式自拟;编程语言采用C/C++。

实验目的:掌握单向链表的基本操作以及基于链表的多项式加法与乘法。

参考:【数据结构】——多项式乘法_数据结构两个多项式相乘-CSDN博客

数据结构设计简要描述:

采用带附加头结点单向链表;每个结点包括双精度类型的系数域、整型类型的指数域和一个指针域。

typedef struct polynode

{

   double c;         //系数

   int e;            //指数

   struct polynode *next;      //指针域,按指数升序连接

}PNode,*Polyn;                 

算法设计简要描述:

 如图所示,可将多项式乘法转化成多项式的加法,利用多项式的加法的算法来实现。

输入/输出设计简要描述:

从ploynode1和ploynode2两个txt文件中分别读取两个多项式的信息,并存储到两个不同数组中,再通过数组构建两个多项式链表(读取到数组元素为0时为止)。每个文件中按每一项系数、指数依次排列,由一个空格隔开。结果输出到multipoly.txt的文件,采用左对齐,每个整数采用5列字符域宽。并且添加了测试的输出函数,将两个多项式和运算结果输出在屏幕上。

编程语言说明:

使用Visual studio 2022编程。主要代码采用C语言实现 ;动态存储分配采用C++的new和delete操作符实现;输入与输出采用C++的cin和cout流;程序注释采用C/C++规范。

主要函数说明:

void Read(const char* s)             //从文件读取数据

void Write(Polyn h)                  //将结果输出到文件中

Polyn Create(const char* s)          //建立链表

void PrintPoly(Polyn h)              //附加测试函数,按多项式的形式将结果打印到控制台界面中

Polyn addpoly(Polyn h1, Polyn h2)   //实现两个多项式的相加,返回和式头指针

Polyn mulpoly(Polyn hp, Polyn hq)  //实现两个多项式的相乘

代码:

#include <iostream>
#include <fstream>
#define MULTIPOLY "multipoly.txt"
#define POLYNODE1 "polynode1.txt"
#define POLYNODE2 "polynode2.txt"

using namespace std;
//定义结点及结点指针数据类型
typedef struct polynode
{
	double c;			        //系数
	int e;				        //指数
	struct polynode* next;		        //要求结点按指数e升序连接
}PNode, * Polyn;                                  //PNode为结点类型,Polyn为结点指针类型
Polyn h1, h2;					//两个多项式P(x),Q(x)的头结点
double a[20]={0};					//数组a保存系数
int b[20]={0};				        //数组b保存指数
void Read(const char* s)		 		//读取数据,s代入不同的文件名
{
	double c;
	int i = 0, e;
	ifstream infile(s);
	if (!infile)				//打开文件失败输出提示信息
	{
		cout << "file open error!" << endl;
		exit(0);
	}
	while (1)                               //打开成功,将系数和指数保存在两个数组中
	{
		if (infile.eof())
			break;
		infile >> c >> e;
		a[i] = c;
		b[i] = e;
		i++;
	}
	infile.close();
}
void Write(Polyn h)				//输出函数,将结果输出到文件中,h为链表头结点
{
	ofstream outfile(MULTIPOLY);       //输出文件名为multiply.txt
	Polyn p = h->next;                      //去掉附加头结点
	if (!outfile)				//打开文件失败输出提示信息
	{
		cout << "file open error!" << endl;
		exit(0);
	}
	if (!p)			                //第一个结点为空,表示运算结果为0
		outfile << "0" << endl;
	while (p)			        //p不为空,依次输出系数和指数
	{
		outfile.width(5);//置输出宽度为5
		outfile.setf(ios::left);//左对齐
		outfile << p->c << " " << p->e << endl;
		p = p->next;
	}
	outfile.close();
}
Polyn Create(const char* s)			        //先入先出建立链表,s代入不同的文件名
{
	int i = 0;                             //i用于记录数组下标
	Polyn h;
	h = new PNode;
	h->next = NULL;                        //h为附加头结点
    Polyn q, p;
	q = h;
	Read(s);                               //从文件中读取系数和指数
	while (a[i] != 0)
	{
		p = new PNode;
		p->c = a[i];
		p->e = b[i];
		p->next = NULL;		      //建新结点
		q->next = p;
		q = p;                     //新结点插入到链表尾
		i++;
	}
	return h;
}

void PrintPoly(Polyn h)                        //按多项式的形式将结果打印到控制台界面中
{
	Polyn p = h->next;
	if (!p)                               //所得结果为空,则输出0
		cout << "0" << endl;
	while (p)
	{
		if (p->next)                     //p不是尾结点
		{
			if (p->next->c < 0)         //p的后继结点的系数小于0,不输出符号 +
			{
				if (p->c == -1)     //p的后继结点的系数等于-1
				{
					cout << "-x^" << p->e;
				}
				else if (p->c == 1) //p的后继结点的系数等于1
				{
					cout << "x^" << p->e;
				}
				else
				{
					cout << p->c << "x^" << p->e;
				}
			}
			else if (p->next->c > 0)       //p的后继结点的系数大于0,需输出符号+
			{
				if (p->c == 1)         //p的后继结点的系数等于1
				{
					cout << "x^" << p->e << "+";
				}
				else if (p->c == -1)   //p的后继结点的系数等于-1
				{
					cout << "-x^" << p->e << "+";
				}
				else
				{
					cout << p->c << "x^" << p->e << "+";
				}
			}
		}
		else                               //p是尾结点,需在结尾输出换行
		{
			if (p->c < 0)              //p的指数小于0
			{
				if (p->c == -1)
				{
					cout << "-x^" << p->e << endl;
				}
				else
				{
					cout << p->c << "x^" << p->e << endl;
				}
			}
			else if (p->c > 0)         //p的指数大于0
			{
				if (p->c == 1)
				{
					cout << "x^" << p->e << endl;
				}
				else
				{
					cout << p->c << "x^" << p->e << endl;
				}
			}
		}
       p = p->next;//指针后移
	}
}
void CreateNode(Polyn& p)			//创建新结点
{
	p = new PNode;
}
void DeleteNode(Polyn& p)			//删除结点
{
	delete p;
}
Polyn addpoly(Polyn h1, Polyn h2)                   //实现两个多项式的相加,返回和式头指针
{
	Polyn p1, p2, p3, h, p;			//h为和式R(x)的附加头结点指针
	p1 = h1->next;
	p2 = h2->next;
	CreateNode(h);
	p3 = h;
	while (p1 && p2)
	{
		if (p1->e < p2->e)              //p1的指数大于p2,先保存p1结点
		{
			p = p1;
			p1 = p1->next;
		}
		else if (p2->e < p1->e)         //p2的指数大于p1,先保存p2结点
		{
			p = p2;
			p2 = p2->next;
		}
		else                             //p1与p2指数相等时
		{
			p1->c += p2->c;         //系数相加,结果保存在p1中
			if (p1->c == 0)         //系数之和为0,则删除该结点
			{
				p = p1;
				p1 = p1->next;
				DeleteNode(p);        //删除结点
				p = p2;
				p2 = p2->next;
				DeleteNode(p);
				continue;
			}
			p = p2;                 //系数之和不为0时,先删除p2结点
			p2 = p2->next;
			DeleteNode(p);
			p = p1;                 //将p1连接到p中
			p1 = p1->next;
		}
		p3->next = p;                 //插入p结点至和式末尾
		p3 = p;
	}
	if (p1)                              //p1没有结束,将p1后面所有的结点连接到和式
		p3->next = p1;
	else if (p2)                         //p2没有结束,将p2后面所有的结点连接到和式
		p3->next = p2;
	else
		p3->next = NULL;
	h1->next = h2->next = NULL;         //清空h1和h2链表
	return h;
}
Polyn mulpoly(Polyn hp, Polyn hq)		    //实现两个多项式的相乘
{
	Polyn hr, ht, q, p, pt;
	CreateNode(hr);
	hr->next = NULL;                     //R(x) = 0
	CreateNode(ht);
	ht->next = NULL;                     //T(x) = 0
	q = hq->next;
	while (q)
	{
		pt = ht;
		p = hp->next;
		while (p)
		{
			CreateNode(pt->next);	//创建新的尾结点
			pt = pt->next;
			pt->c = p->c * q->c;      //系数相乘
			pt->e = p->e + q->e;    //指数相加
			p = p->next;
		}
		pt->next = NULL;
		q = q->next;
		p = addpoly(hr, ht);                 //实现R(x) = R(x) + T(x)
		DeleteNode(hr);
		hr = p;
	}
	DeleteNode(ht);
	return hr;
}
int main()
{
	Polyn h1, h2, h3;                     //定义单向链表附加头结点指针
	cout << "读取文件,直到读入0时停止,建立单向链表" << endl;
	h1 = Create(POLYNODE1);
	h2 = Create(POLYNODE2);
	cout << "P(x) = ";
	PrintPoly(h1);
	cout << "Q(x) = ";
	PrintPoly(h2);
	h3 = mulpoly(h1, h2);
	cout << "R(x) = P(x) * Q(x) = ";
	PrintPoly(h3);
	Write(h3);                             //写入文件
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guts350

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值