实验内容及要求:
从字符文件输入两个多项式的非零系数及对应的指数,建立多项式的链式存储结构,计算这两个多项式的乘积,输出乘积多项式的全部非零系数及对应的指数到另一字符文件中。
要求输入输出字符文件中的数据格式自拟;编程语言采用C/C++。
实验目的:掌握单向链表的基本操作以及基于链表的多项式加法与乘法。
数据结构设计简要描述:
用单链表来储存多项式,定义结构体 PolyNode,结构体中又定义了结构体指针用于链接,在数据域中定义了系数c和指数e.
算法设计简要描述:
用多项式的加法来代替多项式的乘法,设计了Add()函数和Multiply()函数只需要在乘法的函数中循环遍历一个多项式,并调用对应的加法函数就可以实现多项式的乘法.
输入/输出设计简要描述:
定义了Read()函数从文件中读取系数和指数存入对应的数组中,定义了Wirte()函数将结果输入到文件中,再在主函数中将结果打印在控制台.
编程语言说明:
C++
主要函数说明:
定义Read()函数来读取字符文件中的指数和系数;定义 Create()函数来创建链表;用Add()函数实现两个多项式的相加;Multiply()函数用来将一个多项式与另一个多项式的所有项单独相乘再相加最终实现两个多项式的相乘.
程序测试简要报告:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <fstream>
#include<string>
#define Path1 "PolyNode1.txt"
#define Path2 "PolyNode2.txt"
#define Path3 "Multiply.txt"
using namespace std;
//定义结点及结点指针数据类型
typedef struct PolyNode
{
double c; //系数
int e; //指数
struct PolyNode* next;
}PNode, * PolyN; //PNode为结点类型,PolyN为结点指针类型
PolyN h1, h2; //两个多项式P(x),Q(x)的头结点
double a[20]; //数组a保存系数
int b[20]; //数组b保存指数
void Read(string s) //读取数据,s代入不同的文件名
{
double c;
int i = 0, e;
ifstream infile(s);
if (!infile) //打开文件失败输出提示信息
{
cout << "file open error!" << endl;
exit(0);
}
while (infile >> c >> e) //打开成功,将系数和指数保存在两个数组中
{
if (infile.eof())
break;
a[i] = c;
b[i] = e;
i++;
}
infile.close();
}
//输出函数,将结果输出到文件中,h为链表头结点
void Write(PolyN h)
{
ofstream outfile(Path3);
PolyN p = h->next;
if (!outfile)
{
cout << "file open error!" << endl;
exit(0);
}
if (!p)
outfile << "0" << endl;
//p不为空,依次输出系数和指数
while (p)
{
outfile << p->c << " " << p->e << endl;
p = p->next;
}
outfile.close();
}
//建立链表,s代入不同的文件名
PolyN Create(string s)
{
int i = 0;
PolyN h, last, p;
h = new PNode;
h->next = NULL;
last = h;
Read(s);
while (a[i] != 0)
{
p = new PNode;
p->c = a[i];
p->e = b[i];
p->next = NULL; //建新结点
last->next = p;
last = p; //新结点插入到链表尾
i++;
}
return h;
}
//创建新结点
void CreateNode(PolyN& p)
{
p = new PNode;
}
//删除结点
void DeleteNode(PolyN& p)
{
delete p;
}
//实现两个多项式的相加
PolyN Add(PolyN h1, PolyN h2)
{
PolyN p1, p2, p3, h, p;
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 Multiply(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 = Add(hr, ht); //实现R(x) = R(x) + T(x)
DeleteNode(hr);
hr = p;
}
DeleteNode(ht);
return hr;
}
//打印结果
void PrintPoly(PolyN h)
{
PolyN p = h->next;
//所得结果为空,则输出0
if (!p)
cout << "0" << endl;
while (p)
{
//p不是尾结点
if (p->next)
{
//p的后继结点的系数等于1
if (p->c == 1)
{
cout << "x^" << p->e << "+";
p = p->next;
}
else
{
cout << p->c << "x^" << p->e << "+";
p = p->next;
}
}
//p是尾结点,需在结尾输出换行
else
{
if (p->c == 1)
{
cout << "x^" << p->e << endl;
p = p->next;
}
else
{
cout << p->c << "x^" << p->e << endl;
p = p->next;
}
}
}
}
int main()
{
PolyN h1, h2, h3;
h1 = Create(Path1);
h2 = Create(Path2);
cout << "P(x) = ";
PrintPoly(h1);
cout << "Q(x) = ";
PrintPoly(h2);
h3 = Multiply(h1, h2);
cout << "R(x) = P(x) * Q(x) = ";
PrintPoly(h3);
Write(h3);
return 0;
}