一元多项式计算机

一元多项式计算机

一,目的

掌握顺序表和单链表的存储特点及插入、删除等算法。

二,描述

设有一元多项式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^-14x^2 -2x^-1 +9x^3
减法-3x^2 +4x^-5+7-5x^2 +9x^4 -7x^-5+7
乘法3+7x^5 +6x^-34x^-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");
        }
    }
}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值