一元多项式计算机
一,目的
掌握顺序表和单链表的存储特点及插入、删除等算法。
二,描述
设有一元多项式Am(x)和Bn(X),编程实现多项式Am(x)和Bn(x)的加法、减法和乘法运算。其中多项式描述为:
Am(x)=A0+A1x1+A2x2+A3x3+….+Amxm;
Bn(x)=B0+B1x1+B2x2+B3x3+….+Bnxn。
(1)输入:
从键盘输入运算指令(相加、相减、相乘),根据运算指令进行相应运算;
从键盘输入两个多项式的系数和指数;
系数和指数采用int类型,运算结果不超出int取值范围。
(2)输出:
每种运算结果以多项式形式输出,要输出升幂和降幂两种情况。
结果多项式中无重复阶项、无零系数项,输出多项式时请采用如下易读形式(一元多项式,总变元为x): x^4 - 3 x^2 + 5
三,测试方案
多项式一 | 多项式二 | |
---|---|---|
加法 | 3+2x^5 +5x^3 -8x^-1 | 4x^2 -2x^-1 +9x^3 |
减法 | -3x^2 +4x^-5+7 | -5x^2 +9x^4 -7x^-5+7 |
乘法 | 3+7x^5 +6x^-3 | 4x^-5 +5x^2 +7x^4 |
- 加法
- 减法
- 乘法
四,程序源码
DS.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
//Status 是函数类型,其值是函数结果状态码
typedef int Status;
LinkList.h
#include "DS.h"
typedef struct{
float coef;
int expn;
}term, ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*Link,*Position;
typedef struct{
Link head, tail;
int len;
}LinkList;
typedef LinkList polynomial;
void menu();
void CreatPolyn(polynomial &P, int m); //输入m项的系数和指数,表示一元多项式的有序链表P
void DestroyPolyn(polynomial &P); //销毁一元多项式P
void PrintPolyn(polynomial P); //打印出一元多项式P
void Reverse_Linklist(polynomial L); //倒置
int PolynLength(polynomial P); //返回一元多项式P的项数
int cmp(term a, term b);
Status InitList(LinkList &P); //构造一个空的线性链表
Link GetHead(LinkList L); //返回线性表L的头结点位置
Status LocateElem(polynomial P, ElemType e, Link &q, int(*compare)(ElemType, ElemType));
Status MakeNode(Link &p, ElemType e); //分配由p指向的值为e的节点
Status InsFirst(Link h, Link s); //已知h指向线性链表的头节点,将s所指的节点插入在第一个节点之前
Position NextPos(LinkList P, Link l); //已知P指向线性表L中的一个节点,返回p所指节点的直接后继位置
ElemType GetCurElem(Link p); //已知p指向线性链表中的一个节点,返回p所指节点中数据元素的值
Status SetCurElem(Link &p, ElemType e); //已知p指向线性链表中的一个节点,用e更新p所指节点中数据元素的值
Status DelFirst(Link h, Link &q); //已知h指向线性链表的头结点,删除线性链表的第一个节点并以q返回
void FreeNode(Link &p); //清空节点p
Status Append(LinkList &L, Link s);
Status ListEmpty(LinkList L); //若l是空表返回TURE
void AddPolyn(polynomial &Pa, polynomial &Pb); //多项式相加
void SubtractPolyn(polynomial &Pa, polynomial &Pb); //多项式相减
void MultiplyPolyn(polynomial &Pa, polynomial &Pb); //多项式相乘
LinkList.cpp
#include "LinkList.h"
void menu()
{
printf(" 一元多项式计算器 输入'0'退出\n\n");
printf("\t1.加法\n");
printf("\t2.减法\n");
printf("\t3.乘法\n\n");
}
Status InitList(LinkList &P)
{//构造一个空的线性链表
if((P.head = P.tail = (Link)malloc(sizeof(LNode))) == NULL)
{
printf("不能分配空间\n");
}
P.len = 0;
P.head->next = NULL;
return OK;
}
void CreatPolyn(polynomial &P, int m)
{//创建一元多项式
Link h, s = NULL ;
ElemType e;
Link q = (Link)malloc(sizeof(LNode)) ;
Link last = (Link)malloc(sizeof(LNode)) ;
InitList(P); h = GetHead(P);
e.coef = 0.0; e.expn = -1;
SetCurElem(h, e);
for(int i=1; i<=m; ++i){
scanf("%f%d",&e.coef,&e.expn);
switch(LocateElem(P,e,q,cmp))
{
case 0 :
break ;
case 1 :
if(MakeNode(s,e))
{
if(InsFirst(q,s))
{
P.len++ ;
}
}
break ;
case -1 :
if(MakeNode(s,e))
{
last = P.tail ;
last->next = s ;
P.tail = s ;
P.len++ ;
}
break ;
}
}
}
void DestroyPolyn(polynomial &P)
{//销毁一元多项式P
// Link h = (Link)malloc(sizeof(LNode));
Link h = P.head;
Link temp;
while(h!= NULL)
{
temp = h;
h = h->next;
free(temp);
}
}
void PrintPolyn(polynomial P)
{//打印出一元多项式P
Link h = P.head->next;
printf("%.1fx^%d",h->data.coef,h->data.expn);
h = h->next;
while(h !=NULL)
{
if(h->data.coef >= 0)
printf("+%.1fx^%d",h->data.coef,h->data.expn);
else
printf("%.1fx^%d",h->data.coef,h->data.expn);
h = h->next;
}
printf("\n\n\n");
}
void Reverse_Linklist(polynomial L)
{//倒置
Link p, q ;
p = L.head->next;
L.head->next = NULL;
while(p)
{
q = p;
p = p->next;
q->next = L.head->next;
L.head->next = q;
}
}
int PolynLength(polynomial P)
{//返回一元多项式P的项数
return P.len;
}
int cmp(term a, term b)
{
if(a.expn==b.expn)
return 0 ;
else
return (a.expn-b.expn)/abs(a.expn-b.expn);
}
Link GetHead(LinkList L)
{//返回线性表L的头结点位置
return L.head;
}
Status LocateElem(polynomial P, ElemType e, Link &q, int(*compare)(ElemType, ElemType))
{
Link pre = (Link)malloc(sizeof(LNode));
Link temp = (Link)malloc(sizeof(LNode));
ElemType t;
temp = P.head->next;
pre = P.head;
while(temp != NULL)
{
t = temp->data;
switch((*compare)(t,e))
{
case 1://t>e
q = pre;
return 1;
break;
case 0://相同
return 0;
break ;
}
pre = pre->next;
temp = temp->next ;
}
return -1;
}
Status MakeNode(Link &p, ElemType e)
{//分配由p指向的值为e的节点
if((p= (Link)malloc(sizeof(LNode))) != NULL)
{
p->data = e;
p->next = NULL;
return TRUE;
}
return FALSE;
}
Status InsFirst(Link h, Link s)
{ //已知h指向线性链表的头节点,将s所指的节点插入在第一个节点之前
Link temp;
if((temp = (Link)malloc(sizeof(LNode))) != NULL)
{
temp = h->next;
s->next = temp;
h->next = s;
return OK;
}
return FALSE;
}
Position NextPos(LinkList P, Link l)
{//已知l指向线性表P中的一个节点,返回l所指节点的直接后继位置
Link cur = P.head;
while(cur != l && cur != NULL)
cur = cur->next;
if(cur == NULL)
return NULL;
else
return cur->next;
}
ElemType GetCurElem(Link p)
{//已知p指向线性链表中的一个节点,返回p所指节点中数据元素的值
return p->data;
}
Status SetCurElem(Link &p, ElemType e)
{//已知p指向线性链表中的一个节点,用e更新p所指节点中数据元素的值
if(p == NULL)
{
printf("Error\n");
return ERROR;
}
else
{
p->data = e;
return OK;
}
}
Status DelFirst(Link h, Link &q)
{//已知h指向线性链表的头结点,删除线性链表的第一个节点并以q返回
Link temp;
if(NULL == h->next){
q = NULL;
return ERROR;
}
temp = h->next;
h->next = h->next->next;
q = temp;
return OK;
}
void FreeNode(Link &p)
{//清空节点p
if(p != NULL){
free(p);
p = NULL;
}
}
Status Append(LinkList &L, Link s)
{
int count = 0;
L.tail->next = s;
while(s != NULL)
{
L.tail = s;
s = s->next;
count++;
}
L.len += count;
return TRUE;
}
Status ListEmpty(LinkList L)
{//若l是空表返回TURE
if(L.head == L.tail)
return TRUE;
else
return FALSE;
}
void AddPolyn(polynomial &Pa, polynomial &Pb) {
Link ha, hb, qa, qb;
term a, b;
ha = GetHead(Pa); hb = GetHead(Pb); //ha和hb分别指向Pa和Pb的头结点
qa = NextPos(Pa,ha); qb = NextPos(Pb,hb); //qa和qb分别指向ha和hb中的后继
while(qa && qb){
a = GetCurElem(qa); b = GetCurElem(qb);
switch(cmp(a, b)){
case -1: //多项式Pa中当前节点的指数值小
ha = qa; qa = NextPos(Pa, qa); break;
case 0 : //两者指数相等
a.coef = a.coef + b.coef;
if(a.coef != 0.0){
SetCurElem(qa, a); ha = qa;}
else{
if(DelFirst(ha, qa)) Pa.len--;
FreeNode(qa);
}
DelFirst(hb, qb); FreeNode(qb);
qb = NextPos(Pb, hb); qa = NextPos(Pa, ha);
break;
case 1:
DelFirst(hb, qb); InsFirst(ha, qb);
qb = NextPos(Pb, hb); ha = NextPos(Pa, ha);
break;
}
}
if(!ListEmpty(Pb)) Append(Pa, qb);
FreeNode(hb);
}
void SubtractPolyn(polynomial &Pa, polynomial &Pb){
Link ha, hb, qa, qb;
term a, b;
ha = GetHead(Pa); hb = GetHead(Pb); //ha和hb分别指向Pa和Pb的头结点
qa = NextPos(Pa,ha); qb = NextPos(Pb,hb); //qa和qb分别指向ha和hb中的后继
while(qa && qb){
a = GetCurElem(qa); b = GetCurElem(qb);
switch(cmp(a, b)){
case -1: //多项式Pa中当前节点的指数值小
ha = qa; qa = NextPos(Pa, qa); break;
case 0 : //两者指数相等
a.coef = a.coef - b.coef;
if(a.coef != 0.0){
SetCurElem(qa, a); ha = qa;}
else{
if(DelFirst(ha, qa)) Pa.len--;
FreeNode(qa);
}
DelFirst(hb, qb); FreeNode(qb);
qb = NextPos(Pb, hb);
qa = NextPos(Pa, ha);
break;
case 1 : //多项式Pb中当前节点的指数值小
b.coef = -b.coef;
SetCurElem(qb, b);
DelFirst(hb, qb); InsFirst(ha, qb);
qb = NextPos(Pb, hb); ha = NextPos(Pa, ha);
break;
}
}
if(!ListEmpty(Pb)){
while(qb != NULL){
qb->data.coef = -qb->data.coef;
qb = NextPos(Pb, qb);
}
qb = hb->next;
Append(Pa, qb);
FreeNode(hb);
}
}
void MultiplyPolyn(polynomial &Pa, polynomial &Pb){
Link s, pa, pb, haa, hbb;
pa = Pa.head->next; pb = Pb.head->next;
ElemType e;
polynomial Paa, Pbb;
InitList(Paa);
haa = GetHead(Paa);
haa->data.coef = 0.0; haa->data.expn = -1;
for(int i=1; i<=Pa.len; i++){//新建一个多项式Paa,把Pa的值复制进去
e.coef = pa->data.coef;
e.expn = pa->data.expn;
MakeNode(s, e); InsFirst(haa, s);
haa = haa->next;
pa = pa->next;
Paa.len++ ;
Paa.tail = haa;
}
int num = Pa.len;
for(int i=1; i<=Pb.len; i++){
pa = Paa.head->next;
InitList(Pbb);
hbb = GetHead(Pbb);
hbb->data.coef = 0.0; hbb->data.expn = -1;
for(int j=0; j<num; j++){//把Pa与Pb的乘积放在Pbb里
e.coef = pa->data.coef * pb->data.coef;
e.expn = pa->data.expn + pb->data.expn;
MakeNode(s, e);
InsFirst(hbb, s);
hbb = hbb->next;
pa = pa->next;
Pbb.tail = hbb ;
Pbb.len++ ;
}
AddPolyn(Pa, Pbb);//把Pbb的值加到Pa里
DelFirst(Pb.head, pb);
FreeNode(pb);
pb = NextPos(Pb,Pb.head);
}
SubtractPolyn(Pa, Paa); //减去Pa里初始的Paa值
}
main.cpp
#include "LinkList.h"
int main()
{
int choice;
while(1)
{
menu();
int m;
polynomial Pa, Pb;
printf("请输入算指令: ");
scanf("%d",&choice);
switch(choice)
{
case 1://加法
printf("请输入多项式A的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pa, m);
PrintPolyn(Pa);
printf("请输入多项式B的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pb, m);
PrintPolyn(Pb);
AddPolyn(Pa, Pb);
printf("==运算结果==\n");
printf("正序:");
PrintPolyn(Pa);
Reverse_Linklist(Pa);
printf("逆序:");
PrintPolyn(Pa);
DestroyPolyn(Pa);
break;
case 2://减法
printf("请输入多项式A的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pa, m);
PrintPolyn(Pa);
printf("请输入多项式B的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pb, m);
PrintPolyn(Pb);
SubtractPolyn(Pa, Pb);
printf("==运算结果==\n");
printf("正序:");
PrintPolyn(Pa);
Reverse_Linklist(Pa);
printf("逆序:");
PrintPolyn(Pa);
DestroyPolyn(Pa);
break;
case 3://乘法
printf("请输入多项式A的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pa, m);
PrintPolyn(Pa);
printf("请输入多项式B的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pb, m);
PrintPolyn(Pb);
MultiplyPolyn(Pa, Pb);
printf("==运算结果==\n");
printf("正序:");
PrintPolyn(Pa);
Reverse_Linklist(Pa);
printf("逆序:");
PrintPolyn(Pa);
DestroyPolyn(Pa);
break;
case 0:
return 0;
break;
default:
printf("输入错误,请重新输入\n");
}
}
}
printf("请输入多项式B的项数: ");
scanf("%d", &m);
printf("请输入%d对系数指数:\n ",m);
CreatPolyn(Pb, m);
PrintPolyn(Pb);
MultiplyPolyn(Pa, Pb);
printf("==运算结果==\n");
printf("正序:");
PrintPolyn(Pa);
Reverse_Linklist(Pa);
printf("逆序:");
PrintPolyn(Pa);
DestroyPolyn(Pa);
break;
case 0:
return 0;
break;
default:
printf("输入错误,请重新输入\n");
}
}
}