实验内容及要求:
从字符文件输入两个多项式的非零系数及对应的指数,建立多项式的链式存储结构,计算这两个多项式的乘积,输出乘积多项式的全部非零系数及对应的指数到另一字符文件中。
要求输入输出字符文件中的数据格式自拟;编程语言采用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;
}