一元稀疏多项式计算

 


 
 

一、基本概念

  设 a0,a1,…,an都是数域 F 中的数, n 是非负整数,那么表达式anxn +an-1xn-1+…+a2x2 +a1x1+ a0x0(an≠0) 叫做数域 F上一个文字 x 的多项式或一元多项式
  在多项式中,a0叫做零次多项式或常数项,a1x 叫做一次项,一般,aix 叫做i次项,ai 叫做 i 次项的系数。一元多项式用符号 f(x),g(x),…来表示。
  一元稀疏多项式: 在一元多项式中,若系数为0的项数目(也就是不存在的项,指的是比最高次低的项)远远多于非0项的数目(存在的项),并且非0项分布没有规律时,则称该一元多项式为一元稀疏多项式。
 
 

二、问题描述

  1. 输出多项式,输出形式为整数序列:n,a1,e1,a2,e2,…,an,en,其中n是多项式的项数,ai,ei分别是第i 项的系数和指数,序列按指数降序排列。
  2. 实现多项式a和b相加。
  3. 实现多项式a和b相减。
  4. 实现多项式a和b相乘。

输入举例:
   7-5x2+9x5— >3 7 0 -5 2 9 5

测试用例:
  (x + x2) + 0 = x + x2
  (x + x2) - (x + x2) = 0
  0 + 0 = 0
  (x + x2) + (-x + 5x5) = x2 + 5x5

 
 

三、多项式存储

  一元稀疏多项式用链表存储效率较高。

typedef struct Polynomial{//项 
	float coef;//系数 
	int expn;//指数 
	struct Polynomial *next;//指针,下一个项 
}Polynomial;

  程序中的链表,都是带有头结点的,可以方便链表的操作。
  以多项式x + x2的存储为例。如下图:
多项式存储
一元稀疏多项式链表构建代码:

void createPolynomial(Polynomial *head){
	printf("请输入项数:");
	int n;
	scanf("%d",&n);//获取项数
	
	for(int i=1;i<=n;i++){
		Polynomial *p = (Polynomial *)malloc(sizeof(Polynomial));
		printf("请输入第%d项的系数和指数:",i);
		scanf("%f %d",&p->coef,&p->expn);
		if(p->coef == 0)//系数为0,不存储 
			free(p);
		else{
			Polynomial *p1, *p2;//两个指针一前一后便于操作 
			p1 = head;
			p2 = head->next;
			
			while(p2 != NULL && p2->expn < p->expn){//找到指数大于p的 / 或者为空 
				p1 = p2;
				p2 = p2->next;
			}
			if(p2 != NULL && p2->expn == p->expn){//指数相等,合并 
				p2->coef += p->coef;
				if(p2->coef == 0){//若合并后系数为0,则删除该项 
					p1->next = p2->next;
					free(p2);
				}
				free(p);
			}
			else{//不存在指数相等,则添加在p1后面 
				p->next = p2;
				p1->next = p;
			}
		}
	} 
}

 
 

四、多项式加减法

  
基本思路:所有的多项式的是进行指数排序的,所以我们可以像单调链表的合并一样操作。

  1. 当指数相等时,系数相加(减法时则相减);相加完的系数若不为0,则存进链表C;
  2. 若指数不相等,若A的指数小于B的,将A的节点里的系数,指数都存进链表C;
  3. 反之,则将B的节点里的系数,指数都存进链表C;
  4. 当有一个链表的后几项多出来时,也将其存进链表C。

多项式加减法的代码实现:index控制加减,1为加,-1为减;A+B或A-B;返回结果链表

Polynomial* addPolynomial(Polynomial *headA, Polynomial *headB,int index){//headA:多项式A;headB:多项式B;index:加减法标记,加法1,减法-1 
	Polynomial *headC = (Polynomial *)malloc(sizeof(Polynomial));//创建多项式c 
	headC->next = NULL;
	
	Polynomial *a1 = headA, *a2 = headA->next;//多项式A设置两个标记
	Polynomial *b1 = headB, *b2 = headB->next;//多项式B设置两个标记 
	Polynomial *c1 = headC;//多项式C的尾部标记 
	
	while(a2 && b2){//循环比较,指数小的放前面 
		if(a2->expn < b2->expn){//a2的指数小于b2,则将a2放入c的尾 
			a1->next = a2->next;//将a2从a中分离出来 
			a2->next = c1->next;
			c1->next = a2;//将a2接在c的尾 
			
			a2 = a1->next;//a2指向a1的后一个结点 
			c1 = c1->next;//c1移动到c的尾(由于刚刚添加了一个,所以往后移一个) 
		}
		else if(a2->expn == b2->expn){//a2和b2指数相同,两者合并,在放入c的尾 
			a2->coef += index * b2->coef;//系数和,设置index可以控制加减法 
			if(a2->coef != 0){//合并后系数不为0,需要将合并后的a2加入c 
				a1->next = a2->next;//将a2从a中分离出来 
				a2->next = c1->next;
				c1->next = a2;//将a2接在c的尾 
				
				c1 = c1->next;//c1移动到c的尾(由于刚刚添加了一个,所以往后移一个) 
				a2 = a1->next;//a2指向a1的后一个节点 
				b1->next = b2->next;//将b2也分离出来 
				free(b2);//释放b2的空间 
				b2 = b1->next;//b2指向b1的后一个节点 
			}
			else{//合并后系数为0,则不需要加入到c中 
				a1->next = a2->next;//将a2去除 
				free(a2);//释放a2空间 
				a2 = a1->next;
				b1->next = b2->next;//将b2去除 
				free(b2);//释放b2空间 
				b2 = b1->next;
			}
		}
		else{//b2的指数小于a2,则将b2放入c的尾 
			b1->next = b2->next;//将b2从b中分离出来 
			b2->next = c1->next;
			c1->next = b2;//将b2接在c的尾 
			
			b2 = b1->next;//b2指向b1的下一个节点 
			c1 = c1->next;//c1移动到c的尾(由于刚刚添加了一个,所以往后移一个)
		}
	}
	
	while(a2){
		a2->coef *= index;//减,就让系数变号 
		a1->next = a2->next;//将a2接在c后面
		a2->next = c1->next;
		c1->next = a2;
		c1 = c1->next;
		a2 = a1->next;
	} 
	while(b2){
		b2->coef *= index;//减,就让系数变号 
		b1->next = b2->next;//将b2接在c后面 
		b2->next = c1->next;
		c1->next = b2;
		c1 = c1->next; 
		b2 = b1->next;
	}
	
	return headC;//返回多项式c 
}

 
 

五、多项式相乘

基本思路:按位相乘,循环遍历;时间复杂度n2
A = a1xi1+a2xi2
B = b1xi3+b2xi4
A * B = a1*b1xi1+i3 + a1*b2xi1+i4 + a2*b1xi2+i3 + a2*b2xi2+i4

Polynomial* multiplyPolynomial(Polynomial *headA, Polynomial *headB){//A乘B 
	Polynomial *headC = (Polynomial *)malloc(sizeof(Polynomial));//创建多项式c 
	headC->next = NULL;
	
	Polynomial *a1 = headA, *a2 = headA->next;//多项式A设置两个标记
	Polynomial *b1 = headB, *b2 = headB->next;//多项式B设置两个标记 
	Polynomial *c1 = headC;//多项式C的尾部标记 
	
	while(a2){
		b2 = headB->next;
		while(b2){
			Polynomial *p = (Polynomial *)malloc(sizeof(Polynomial));
			p->coef = a2->coef * b2->coef;//系数相差 
			p->expn = a2->expn + b2->expn;//指数相加 
			
			if(p->coef == 0)//系数为0,不存储 
				free(p);
			else{
				Polynomial *p1, *p2;//两个指针一前一后便于操作 
				p1 = c1;
				p2 = c1->next;
				
				while(p2 != NULL && p2->expn < p->expn){//找到指数大于p的 / 或者为空 
					p1 = p2;
					p2 = p2->next;
				}
				if(p2 != NULL && p2->expn == p->expn){//指数相等,合并 
					p2->coef += p->coef;
					if(p2->coef == 0){//若合并后系数为0,则删除该项 
						p1->next = p2->next;
						free(p2);
					}
					free(p);
				}
				else{//不存在指数相等,则添加在p1后面 
					p->next = p2;
					p1->next = p;
				}
			}
			b2 = b2->next;//b2向下移一个 
		}
		a2 = a2->next;//a2向下移一个 
	}
	
	return headC;//返回多项式c 
}
  • 11
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,这是一份简单的一元稀疏多项式计算的C++源代码,利用链表实现加法减法的计算: ```c++ #include <iostream> using namespace std; // 多项式项 class PolyItem { public: int coef; // 系数 int expn; // 指数 PolyItem* next; // 下一个项 }; // 多项式 class Poly { public: Poly() { head = new PolyItem(); head->next = nullptr; } ~Poly() { PolyItem* p = head; while (p) { PolyItem* temp = p; p = p->next; delete temp; } } // 获取多项式项的个数 int GetLength() const { int count = 0; PolyItem* p = head->next; while (p) { count++; p = p->next; } return count; } // 添加多项式项 void AddItem(int coef, int expn) { PolyItem* p = head; while (p->next && p->next->expn > expn) { p = p->next; } if (p->next && p->next->expn == expn) { // 合并同类项 p->next->coef += coef; if (p->next->coef == 0) { // 系数为0,删除该项 PolyItem* temp = p->next; p->next = p->next->next; delete temp; } } else { PolyItem* item = new PolyItem(); item->coef = coef; item->expn = expn; item->next = p->next; p->next = item; } } // 加法运算 void Add(const Poly& b) { PolyItem* pa = head->next; PolyItem* pb = b.head->next; PolyItem* pc = head; while (pa && pb) { if (pa->expn > pb->expn) { pc->next = new PolyItem(); pc = pc->next; pc->coef = pa->coef; pc->expn = pa->expn; pa = pa->next; } else if (pa->expn < pb->expn) { pc->next = new PolyItem(); pc = pc->next; pc->coef = pb->coef; pc->expn = pb->expn; pb = pb->next; } else { int sum = pa->coef + pb->coef; if (sum != 0) { pc->next = new PolyItem(); pc = pc->next; pc->coef = sum; pc->expn = pa->expn; } pa = pa->next; pb = pb->next; } } while (pa) { pc->next = new PolyItem(); pc = pc->next; pc->coef = pa->coef; pc->expn = pa->expn; pa = pa->next; } while (pb) { pc->next = new PolyItem(); pc = pc->next; pc->coef = pb->coef; pc->expn = pb->expn; pb = pb->next; } pc->next = nullptr; } // 减法运算 void Subtract(const Poly& b) { PolyItem* pa = head->next; PolyItem* pb = b.head->next; PolyItem* pc = head; while (pa && pb) { if (pa->expn > pb->expn) { pc->next = new PolyItem(); pc = pc->next; pc->coef = pa->coef; pc->expn = pa->expn; pa = pa->next; } else if (pa->expn < pb->expn) { pc->next = new PolyItem(); pc = pc->next; pc->coef = -pb->coef; pc->expn = pb->expn; pb = pb->next; } else { int diff = pa->coef - pb->coef; if (diff != 0) { pc->next = new PolyItem(); pc = pc->next; pc->coef = diff; pc->expn = pa->expn; } pa = pa->next; pb = pb->next; } } while (pa) { pc->next = new PolyItem(); pc = pc->next; pc->coef = pa->coef; pc->expn = pa->expn; pa = pa->next; } while (pb) { pc->next = new PolyItem(); pc = pc->next; pc->coef = -pb->coef; pc->expn = pb->expn; pb = pb->next; } pc->next = nullptr; } // 显示多项式 void Display() const { PolyItem* p = head->next; while (p) { cout << p->coef << "x^" << p->expn; if (p->next) { cout << " + "; } p = p->next; } cout << endl; } private: PolyItem* head; }; int main() { Poly a, b, c; // 添加多项式项 a.AddItem(3, 2); a.AddItem(4, 1); a.AddItem(5, 0); b.AddItem(1, 2); b.AddItem(-3, 1); b.AddItem(2, 0); // 显示多项式 cout << "a = "; a.Display(); cout << "b = "; b.Display(); // 加法运算 c = a; c.Add(b); cout << "a + b = "; c.Display(); // 减法运算 c = a; c.Subtract(b); cout << "a - b = "; c.Display(); return 0; } ``` 在这个源代码中,我们定义了两个类:PolyItem和Poly。PolyItem表示多项式的一项,包括系数和指数。Poly表示多项式,包括多项式项的链表和一些操作,如添加多项式项、加法运算、减法运算和显示多项式。我们可以创建两个多项式a和b,添加多项式项,然后进行加法和减法运算。最后,我们可以显示结果多项式c。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值