pta--一元多项式的乘法与加法运算(C++map实现)

问题描述:设计函数分别求两个一元多项式的乘积与和。

代码长度限制:16 KB
时间限制:200 ms
内存限制:64 MB

输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。

样例输入:

4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1

样例输出:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0

解题思路:
这个题我用的c++ STL的map容器解的。
因为多项式的表达方式和map的特点有很多相似的地方:

先讲乘法优点:

  1. 多项式中,不会有两项指数相同的项,如果有的话会合并,也是一项。恰好map容器的关键字不能重复。所以我们把每一项的指数定为关键字,每一项的系数定为值,这样map的每项就是多项式的每一项。
  2. 定义三个map对象,mp1,mp2和result,多项式相乘,就是mp1的每一项和mp2的每一项乘积,两项乘积即指数相加,系数相乘。如果result结果中没有关键字是该两项乘积指数的项,那加上这一项,该项的值就是系数乘积。
  3. 多项式相乘,可能乘出来的结果会有合并的情况,比如a* x¹ * b *x³和c * x² * d * x²,这两个相乘的结果可以合并,那无非就是在mp[4]上面添加即可。
  4. 因为map用红黑树实现,在给我们把项按关键字(指数)的同时效率也比较高。既然他给我们排好序了,就便于我们打印了。

加法优点:
先把结果定为第一个多项式,再在第一个多项式中加上第二个。把第二个多项式按项数遍历。如果第二项的指数在第一项有,那就直接把系数加上。如果没有,那就在result中再开一项,开到哪个位置都行,因为map容器自动排序。
附:为啥可以对应项相加?因为map自动排序…

代码实现:

#include<iostream>
#include<map>
using namespace std;
int main( )
{
	map<int, int> mp1, mp2 , mr, ar;//multiple result 和addition result
	//第一个int是指数,关键字,第二个int是系数,值
	map<int, int>::iterator it1, it2;
	int n, m;
	int temp1, temp2;
	//the input of the first map's information
	cin >> n;
	for(int i = 0; i < n; ++ i)
	{
		cin >> temp1 >> temp2;//先输入系数,后输入指数
		mp1[temp2] = temp1;
	}
	//the input of the second map's information
	cin >> m;
	for(int i = 0; i < m; ++ i)
	{
		cin >> temp1 >> temp2;
		mp2[temp2] = temp1;
	}
	//乘法计算,变历让map1和map2中的每一项相乘
	for(it1 = mp1.begin(); it1 != mp1.end(); it1 ++)
	{
		for(it2 = mp2.begin(); it2 != mp2.end(); it2 ++)
		{
			int x = (it1->first) + (it2->first);//两项相乘指数相加
			if(mr.find(x) == mr.end())//结果中没有这个指数时先置系数为0
				mr[x] = 0;
			mr[x] += (it1->second) * (it2->second);//加上新产生的结果
			if(mr[x] == 0)//如果两个结果加起来系数是0了,删除这一项
				mr.erase(x);
		}
	}
	//多项式加法
	ar = mp1;//先把mp1赋给结果
	for(it2 = mp2.begin(); it2 != mp2.end(); it2 ++)
	{
		if(ar.find(it2->first) == ar.end())//原来没这个指数项时置0
			ar[it2->first] = 0;
		ar[it2->first] += it2->second;//加上新结果
		if(ar[it2->first] == 0)//系数为0时清除这一项
			ar.erase(it2->first);
	}
	//output multiple result
	//如果有个多项式为0,乘法结果必为0,或者是乘法算完后结果为0
	if( m == 0 || n == 0 || mr.size() == 0)
		cout << "0 0"<<endl;
	else{
		it2 = mr.end();//先打印指数大的
		it2 --;
		for(it1 = it2; it1 != mr.begin(); it1 --)
				cout << it1->second << ' ' << it1->first << ' ';
			cout << it1->second << ' ' << it1->first <<endl;
	}
	
	//output add result	
	if(ar.size() == 0)
	{
		cout << "0 0"<<endl;
	}
	else{
		it2 = ar.end();
		it2 --;
		for(it1 = it2; it1 != ar.begin(); it1 --)
				cout << it1->second << ' ' << it1->first << ' ';
			cout << it1->second << ' ' << it1->first;
	}
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值