主要代码
/****************************************************
@title: 数据结构实验
@name:<试验> 一元多项式简单计算器
@object:
[实验目的]
单链表的存储结构及其基本操作的实现
[实验提示]
1. 在linklist.h中实现单链表的基本操作
2.在Polynomial.h中实现了一元多项式的基本操作
3.在Polynomial.h中编写代码,进行测试
4.在MutualPlat.h中编写一交互式的运行平台
@include:
ds.h [*]
单链表的实现
@author: wangheng
@date: 3 / 4 / 2017
***************************************************/
#define Number 2.0
#include <stdio.h>
#include <stdlib.h>
#include "MutualPlat.h"
int main()
{
printf("是否进行运算(Y/N): ");
char command;
polynomial P1;
polynomial P2;
read(command);
while(command == 'Y')
{
run(); //运行程序
printf("是否进行运算(Y/N): ");
readM(command);
}
return 0;
}
/*
Name: LinkList.h
Author: WangHeng
Data: 3 / 4 / 2017 ;
Description: 1)建立一个交互式的平台,实现创建和运行运算的功能
2)调用一元多项式的头文件Polynomial.h,进行调用
*/
#ifndef MUTUALPLAT_H_INCLUDED
#define MUTUALPLAT_H_INCLUDED
//////////////////////////////////////////
//应用的头文件
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ds.h"
#include "Polynomial.h"
///////////////////////////////////////////
//输入函数:调用一元多项式的CreatPolyn()函数进行输入
void input (polynomial& P)
{
//1)输入第一个一元多项式各项
printf("\n输入一个一元多项式的各项系数和指数[当输入的系数和指数为:(0 0) 时,输入结束]\n");
CreatPolyn(P);
//打印输出一元多项式P1
PrintPolyn(P);
//输出一元多项式的项数
printf("一元多项式的项数: %d\n",PolynLength(P));
}
//运算方法清单
void CaculateMenu()
{
printf("选择你想进行的运算方法:[A](add),[S](substract),[M](multiply),\n[D](Derivative),[C](Calculus)---");
}
//输入运算命令
Status GetCommand(char& way)
{
printf("\n运算方法为:");
readM(way);
printf("\n");
return OK;
}
//交互式运行平台
void run( )
{
char way;
polynomial P1;
polynomial P2;
//3)选择运算方法
CaculateMenu();
GetCommand(way);
switch(way)
{
case 'A' : //两个一元多项式的和
case 'a':
input(P1); //输入一元多项式的各项
input(P2);
AddPolyn(P1,P2);
//打印输出和
printf("打印输出和:\n");
PrintPolyn(P1);
break;
case 'S' : //两个一元多项式的差
case 's':
input(P1); //输入一元多项式的各项
input(P2);
SubtractPolyn(P1,P2);
//打印输出差
printf("打印输出差:\n");
PrintPolyn(P1);
break;
case 'M' : //两个一元多项式的积
case 'm':
input(P1); //输入一元多项式的各项
input(P2);
MultiplyPolyn(P1,P2);
//打印输出积
printf("打印输出积:\n");
PrintPolyn(P1);
break;
case 'D':
case 'd':
input(P1); //输入一元多项式的各项
Derivative(P1);
//打印输出导数
printf("打印输出 P1 导数: \n");
PrintPolyn(P1);
break;
case 'C':
case 'c':
input(P1); //输入一元多项式的各项
Calculus (P1);
//打印输出积分
printf("打印输出 P1 积分: \n");
PrintPolyn(P1);
break;
default:
printf("输入的运算方法错误:");
}
//销毁一元多项式
DestroyPolyn(P1);
}
#endif // MUTUALPLAT_H_INCLUDED
/*
Name: Polynomial.h
Author: WangHeng
Data: 3 / 4 / 2017 ;
Description: 1)调用LinkList.h头文件,用实现链表的各种功能
来创建一元多项式的各种算法实现;
2)调用ds.h来进行基本的输入输出等操作
3)头文件Polynomial.h主要完成一元多项式的各种操作
*/
#ifndef POLYNOMIAL_H_INCLUDED
#define POLYNOMIAL_H_INCLUDED
#ifndef ElemType
#define ElemType int //数据类型默认为int
#define ELEMTYPE_TAG
#endif
#include "ds.h"
#include "LinkList.h"
typedef LinkList polynomial;
/*************************************************************************
* 基本操作的函数原型说明
*************************************************************************/
//输入m项的系数和指数,建立表示一元多项式的有序链表P
void CreatPolyn(polynomial &P, int m);
//销毁一元多项式P
void DestroyPolyn(polynomial &P);
//打印输出一元多项式P
void PrintPolyn(polynomial P);
//返回一元多项式P中的项数
int PolynLength(polynomial P);
//完成多项式相加运算,即:Pa = Pa + Pb,并销毁一元多项式Pb
void AddPolyn(polynomial &Pa,polynomial &Pb);
//完成多项式相减运算,即:Pa = Pa - Pb,并销毁一元多项式Pb
void SubtractPolyn(polynomial &Pa,polynomial &Pb);
//完成多项式相乘运算,即:Pa = Pa * Pb,并销毁一元多项式Pb
void MultiplyPolyn(polynomial &Pa,polynomial &Pb);
//完成多项式的求导函数,即:Pa = Pa'
void Derivative(polynomial &P);
//完成多项式的积分函数, Pa = ∫Pa' dx
void Calculus (polynomial &P);
/*********************************************************************
* 基本操作的算法描述和实现
*********************************************************************/
//创建一元多项式P,当输入的指数和系数都为0时,输入结束。
// 一元多项式就被创建 。
void CreatPolyn(polynomial &P)
{
InitList(P);
printf(" \n输入系数和指数:\n");
read(P->coef,P->expn); //输入系数和指数
//-------------------TODO------------------//
while(P->coef!=0||P->expn!=0){
ListInsert(P, 1, P->coef, P->expn);
printf(" \n输入系数和指数:\n");
read(P->coef,P->expn);
}
//------------初始化表达式,不断输入系数和指数,直到读到0,0为止----------//
}
//销毁一元多项式P
void DestroyPolyn(polynomial &P)
{
DestroyList(P); //调用LinkList.h头文件中的销毁函数
}
//打印输出一元多项式P
void PrintPolyn(polynomial P)
{
printf("打印一员多项式的各系数和指数\n ");
UnionList(P); //用来合并在一元多项式计算结果中具有相同指数的项
PrintLinkList(P);
}
//返回一元多项式P中的项数
int PolynLength(polynomial P)
{
return ListLength(P); //合并后的一元多项式的项数
}
//完成多项式相加运算,即:Pa = Pa + Pb,并销毁一元多项式Pb
void AddPolyn(polynomial &Pa,polynomial &Pb)
{
UnionList(Pa); //合并一元多项式中具有
UnionList(Pb); //相同指数的项
for (int i=1; i<=ListLength(Pb); i++)
{
float co;
int ex;
GetElem(Pb, i, co, ex);
if(LocateElem(Pa, ex) > 0) //判断Pa中是否具有Pb中相同指数的项,
{ //如果有,进行相加
int j = LocateElem(Pa, ex); //记录Pa中相同项的位置
int k = 0;
polynomial s = Pa;
while(k < j) //查找这一位置
{
//-------------------TODO------------------//
s=s->next;
k++;
}
s->coef += co; //系数项相加
}
else //不存在相同的指数,将Pb中的该项插入Pa
ListInsert(Pa, 1, co, ex);
}
DestroyList(Pb); //销毁Pb
}
//完成多项式相减运算,即:Pa = Pa - Pb,并销毁一元多项式Pb
void SubtractPolyn(polynomial &Pa,polynomial &Pb)
{
UnionList(Pa); //合并一元多项式中具有
UnionList(Pb); //相同指数的项
for (int i=1; i<=ListLength(Pb); i++)
{
float co;
int ex;
GetElem(Pb, i, co, ex);
if(LocateElem(Pa, ex) > 0) //判断Pa中是否具有Pb中相同指数的项,
{ //如果有,进行相加
int j = LocateElem(Pa, ex); //记录Pa中相同项的位置
int k = 0;
polynomial s = Pa;
while(k < j) //查找这一位置
{
//-------------------TODO------------------//
s=s->next;
k++;
}
s->coef -= co;
}
else //不存在相同的指数,将Pb中的该项插入Pa
ListInsert(Pa, 1, co, ex);
}
DestroyList(Pb); //销毁Pb
}
//完成多项式相乘运算,即:Pa = Pa * Pb,并销毁一元多项式Pb
void MultiplyPolyn(polynomial &Pa,polynomial &Pb)
{
UnionList(Pa); //合并一元多项式中具有
UnionList(Pb); //相同指数的项
for (int i=1; i<=ListLength(Pb); i++)
{
float co;
int ex;
GetElem(Pb, i, co, ex);
if(LocateElem(Pa, ex) > 0) //判断Pa中是否具有Pb中相同指数的项,
{ //如果有,进行相加
int j = LocateElem(Pa, ex); //记录Pa中相同项的位置
int k = 0;
polynomial s = Pa;
while(k < j) //查找这一位置
{
//-------------------TODO------------------//
s=s->next;
k++;
}
s->coef *= co; //系数项相加
}
else //不存在相同的指数,将Pb中的该项插入Pa
ListInsert(Pa, 1, co, ex);
}
DestroyList(Pb); //销毁Pb
}
//完成多项式的求导函数,即:Pa = Pa'
void Derivative(polynomial &P)
{
polynomial Pb=P->next;
float co;
int ex;
while(Pb)
{
co=(Pb->coef) * (Pb->expn);
ex=Pb->expn-1;
Pb->coef=co;
Pb->expn=ex;
Pb=Pb->next;
}
DestroyList(Pb); //销毁Pb
}
//完成多项式的积分函数, Pa = ∫Pa' dx
void Calculus (polynomial &P)
{
polynomial Pb=P->next;
float co;
int ex;
while(Pb)
{
ex=Pb->expn+1;
co=Pb->coef/ex;
Pb->coef=co;
Pb->expn=ex;
Pb=Pb->next;
}
DestroyList(Pb);
}
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif
#endif // POLYNOMIAL_H_INCLUDED
/*
Name: LinkList.h
Author: WangHeng
Data: 3 / 4 / 2017 ;
Description: 引用老师的链表结构,在此基础上进行修改,
使其适合一元多项式.
*/
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED
#include "ds.h"
#ifndef ElemType
#define ElemType int //数据类型默认为int
#define ELEMTYPE_TAG
#endif
/****************************************************************
* 多项式的存储结构定义
****************************************************************/
typedef struct LNode{
float coef; //系数
int expn; //指数
struct LNode *next;
} LNode,*LinkList;
/*************************************************************************
* 基本操作的函数原型说明
*************************************************************************/
//创建并初始化为空表
Status InitList(LinkList &L);
//销毁整个表(从此之后不再可用)
Status DestroyList(LinkList &L);
//将表L置空
Status ClearList(LinkList &L);
//判断表L是否为空表
bool ListEmpty(LinkList L);
//求表L的长度
int ListLength(LinkList L);
//取表L中的第i个元素,并用e返回. 操作成功返回OK,失败时返回ERROR
Status GetElem(LinkList L, int i, float &co, int &ex);
template <typename T> bool equal(T a, T b)
{
return a==b;
}
//在表L中定位元素e首次出现的位置. 操作成功返回位序,失败时返回0
// compare(a,b) 为比较函数,匹配时返回true,否则返回false
// 这里默认使用equal进行比较
int LocateElem(LinkList L, int ex,
bool (*compare)(int ,int )=equal<int >);
//在表L中插入第i个元素e. 操作成功返回OK,失败时返回ERROR
Status ListInsert(LinkList &L, int i, float co , int ex);
//删除表L中第i个元素,结果用e返回. 操作成功返回OK,失败时返回ERROR
Status ListDelete(LinkList &L, int i, float &co, int &ex);
//遍历表L,对每个元素调用visit(x).
Status ListTraverse(LinkList L, Status (*visit)(float,int));
//合并一元多项式中相同的幂的项
void UnionList(LinkList &L);
/**********************************************************
* 单链表的基本操作的实现
***********************************************************/
//创建并初始化为空表
Status InitList(LinkList &L)
{
L = (LNode*)malloc(sizeof(LNode));
if(!L) exit(DS_OVERFLOW);
L->next = NULL;
return OK;
}
//销毁整个表(从此之后不再可用)
Status DestroyList(LinkList &L)
{
LinkList p ;
while (L )
{
p = L;
L = L->next;
free(p);
}
return OK;
}
//将表L置空
Status ClearList(LinkList &L)
{
LinkList p = L->next;
LinkList s ;
while (p )
{
s = p;
p = p->next;
free(s);
}
return OK;
}
//判断表L是否为空表
bool ListEmpty(LinkList L)
{
if(L->next == NULL)
return TRUE;
else
return FALSE;
}
//求表L的长度
int ListLength(LinkList L)
{
int j = 0;
LinkList p = L;
while (p ->next != NULL)
{
j++;
p = p->next;
}
return j;
}
//取表L中的第i个元素,并用返回. 操作成功返回OK,失败时返回ERROR
Status GetElem(LinkList L, int i, float &co, int &ex)
{
if(i > ListLength(L) || i <= 0) return ERROR;
int j = 0;
LinkList p = L;
while(p&&j < i)
{
p = p->next;
j++;
}
if(p && j == i)
{
co = p->coef;
ex = p->expn;
return ex;
}
else
return ERROR;
//-------------------------------------
}
//在表L中定位元素e首次出现的位置. 操作成功返回位序,失败时返回0
// compare(a,b) 为比较函数,匹配时返回true,否则返回false
int LocateElem(LinkList L, int ex, bool (*compare)(int , int))
{
// TODO (#1#): 在表中定位元素ex,用compare(a,b)匹配元素
LinkList p;
int j;
p = L->next; j = 0;
while(p) {
j++;
if( compare(p->expn,ex) ) return j;
p=p->next;
}
return 0;
//-------------------------------------
}
//在表L中插入第i个元素e. 操作成功返回OK,失败时返回ERROR
Status ListInsert(LinkList &L, int i, float co, int ex)
{
// TODO (#1#): 在链表中插入元素
LinkList p = L;
int j = 0;
while(p && j < i - 1) //注意判断条件
{
p = p->next ;
j++;
}
if(p && j == i-1)
{
LinkList s = (LNode *)malloc(sizeof(LNode)); //分配插入的结点
if(!s) exit(DS_OVERFLOW);
//-------------------TODO------------------//
s->coef=co;
s->expn=ex;
s->next = p->next;
p->next = s;
return OK;
}
else
return ERROR;
//-------------------------------------
}
//删除表L中第i个元素,结果用e返回. 操作成功返回OK,失败时返回ERROR
Status ListDelete(LinkList &L, int i, float &co, int &ex)
{
// TODO (#1#): 在链表中删除元素
LinkList p = L;
int j = 0;
while(p && j < i-1 ) //注意判断条件
{
p = p->next ;
j++;
}
if(p && j == i-1)
{
LinkList s = p->next;
p->next = s->next;
//-------------------TODO------------------//
co= s->coef;
ex= s->expn;
free(s);
return OK;
}
else
return ERROR;
//-------------------------------------
}
//遍历表L,对每个元素调用visit(x).
Status ListTraverse(LinkList L, Status (*visit)(float,int))
{
LinkList p = L->next;
while ( p ) {
if ( visit(p->coef,p->expn)==ERROR ) return ERROR;
p = p->next;
printf("+\t");
}
return OK;
//--------------------------------------
}
//合并一元多项式中相同的幂的项
void UnionList(LinkList &L)
{
int ex1,ex2;
float co0,co1,co2;
LinkList p = L;
for(int i = 1; i < ListLength(L); i++)
{
GetElem(L, i, co1, ex1);
if(co1 == 0)
ListDelete(L, i, co1, ex1);
for (int j = i+1; j < ListLength(L)+1; j++)
{
GetElem(L, j, co2, ex2);
if(co2 == 0)
ListDelete(L, j, co2, ex2);
else if(ex2 == ex1)
{
co0 = co1 + co2; //解决在同一一元多项式中有相同系数的情况
ListDelete(L, j, co2, ex2);
ListDelete(L, i, co1, ex1);
ListInsert(L, i, co0, ex1);
}
}
}
}
/******************************************************
* 在程序设计时,所需的小型函数
*****************************************************/
// 打印数据元素的方法
Status print(float co,int ex )
{
printf("%.2f X^%2d \t",co,ex);
return OK;
}
//打印链表内容
void PrintLinkList(LinkList L)
{
ListTraverse(L,print); //遍历链表并print()每个元素
printf("\n");
}
bool equal(int a, int b)
{
return a==b;
}
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif
#endif // LINKLIST_H_INCLUDED
演示效果: