一元多项式的表示与加法 乘法 求导 运算

零。        理论知识

        视频:多项式运算

                   多项式运算2

        a.        如何表示

        我们用线性表去表示一元多项式。

struct  Node{
    int r;  // 系数
    int e;  // 指数
};


struct List{
    Node data[10000+5];
    int len;
};

        1.第一个结构体Node中的每一项(节点)都表示一元多项式中的一项,包含了系数r 和 指数e

        2.第二个结构体有两部分。一个是len表示当前的长度,即当前的一元多项式用到了多少项;另一个是一个结构体数组(即Node),结构体数组中的每一项就表示了一元多项式中的一项

        注意: 这里不再是链表了,而只是一个结构体数组

        b.        如何实现功能

        与链表的各个操作类似,线性表去进行一元多项式的运算题目一般也包含两部分

        1.        一个是各个题目都通用的基础函数,如inputlist Printlist.....——见“壹”部分

        2.        另一个则是每道题具体实现要用到的函数,如实现相加功能的函数,实现求导功能的函数......——见“贰”部分

壹。        一元多项式的基本操作函数

        a.        输入函数

// 输入多项式
List InputList()
{
	//先设出变量list,并初始化其中的长度len为0 
	List list;
	list.len = 0;
	
	int r,e;
	
	while(cin>>r>>e)
	{
		if( r==-1 && e==-1 )//输入到-1 -1 则break跳出循环 
		{
			break;
		}
		else
		{
			list.data[list.len].r = r;
			list.data[list.len].e = e;
			list.len++;
		}
	}
	
	return list; 
}

        此时可以巧妙地利用list.len去知道当前输入到第几项了,从而避免了再设一个变量i

        b.        输出函数

// 输出多项式
void PrintList(const List& list)
{
	int l = list.len;
	
	//特判一下结果为0的情况 和 答案多项式为空的情况 
	if( l==0 || l==1 && list.data[0].r==0 )
	{
		cout<<"0";
	} 
	
	for( int i = 0 ; i<l ; i++ )
	{
		cout<<list.data[i].r<<" "<<list.data[i].e<<" ";
	}
	cout<<endl;

}

        就是一个比较简单的数组遍历,但是要注意一些题目中提出的输出要求去进行输出特判(如答案多项式为0......)

贰。        几道题目和其中具体的函数实现

        a.           一元多项式的求和(附加代码模式)

一元多项式的求和(附加代码模式)

题目:

代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct  Node{
    int r;  // 系数
    int e;  // 指数
};

// 线性表存储一元多项式
struct List{
    Node data[10000+5];
    int len;
};

// 输出多项式
void PrintList(const List& list)
{
	int l = list.len;
	
	//特判一下结果为0的情况 和 答案链表为空的情况 
	if( l==0 || l==1 && list.data[0].r==0 )
	{
		cout<<"0";
	} 
	
	for( int i = 0 ; i<l ; i++ )
	{
		cout<<list.data[i].r<<" "<<list.data[i].e<<" ";
	}
	cout<<endl;

}

// 输入多项式
List InputList()
{
	//先设出变量list,并初始化其中的长度len为0 
	List list;
	list.len = 0;
	
	int r,e;
	
	while(cin>>r>>e)
	{
		if( r==-1 && e==-1 )//输入到-1 -1 则break跳出循环 
		{
			break;
		}
		else
		{
			list.data[list.len].r = r;
			list.data[list.len].e = e;
			list.len++;
		}
	}
	
	return list; 
}

// 多项式求和
List add(const List& list1, const List& list2)
{
	//去设出答案多项式 
	List list3;
	list3.len=0;
	
	//用i和j两个指针分别指向list1和list2 从而进行遍历 
	int i = 0 , j = 0;
	int l1 = list1.len , l2 = list2.len;
	
    //去对a和b中的每个节点逐一比较,此时是降幂排列 所以直接一一比较即可
    //while不断循环直到两个数组有一个先被遍历完了
	while( i<l1 && j<l2 )
	{
		if( list1.data[i].e == list2.data[j].e )
		{
			if(list1.data[i].r + list2.data[j].r == 0 )
			{
				i++,j++;
			}
			else
			{
				list3.data[list3.len].e = list1.data[i].e;
				list3.data[list3.len].r = list1.data[i].r + list2.data[j].r;
				i++,j++,list3.len++;
			}
			
		}
		else if( list1.data[i].e > list2.data[j].e )
		{
			list3.data[list3.len].e = list1.data[i].e;
			list3.data[list3.len].r = list1.data[i].r;
			i++,list3.len++;
		}
		else if( list1.data[i].e < list2.data[j].e )
		{
			list3.data[list3.len].e = list2.data[j].e;
			list3.data[list3.len].r = list2.data[j].r;
			j++,list3.len++;
		}
	}
	
    //退出了while循环只能说明其中至少有一个数组循环完了,
    //但另外一个可能还有东西;此时全部加到答案数组后面即可
    //(为了方便 直接写两个while循环避免判断了)
	while( i<l1 )
	{
		list3.data[list3.len].e = list1.data[i].e;
		list3.data[list3.len].r = list1.data[i].r;
		i++,list3.len++;
	}
	
	while( j<l2 )
	{
		list3.data[list3.len].e = list2.data[j].e;
		list3.data[list3.len].r = list2.data[j].r;
		j++,list3.len++;
	}
	
	return list3;
}

int main()
{
    // freopen("/config/workspace/answer/DataStructure/test.in","r",stdin);    
    List list1 = InputList();
    List list2 = InputList();
    List list = add(list1, list2);
    PrintList(list);
    return 0;
}

见实现求和函数的注释:

1.由于本来就是降幂排序,所以直接用两个指针分别指向list1和list2;并不断地进行比较直到有一个list被循环完

2.此时再去把另一个list全部加到答案list里即可(如果有的话)

        b.        一元多项式的乘法运算

一元多项式的乘法运算

题目:

代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>	//因为后面要用到sort函数 

using namespace std;

struct  Node{
    int r;  // 系数
    int e;  // 指数
};

// 线性表存储一元多项式
struct List{
    Node data[10000+5];
    int len;
};

//自定义的比较函数
bool cmp( Node a , Node b )	//要明白此时我们要排序比较的是两个Node 所以传入参数的数据类型是Node 
{
	return a.e>b.e; 	//此时是降序排序 所以是大于号 
} 

// 输出多项式
void PrintList(const List& list)
{
	int l = list.len;
	
	//特判一下结果为0的情况
	if( l==0 || l==1 && list.data[0].r==0 )
	{
		cout<<"0 0";
	} 
	
	for( int i = 0 ; i<l ; i++ )
	{
		if(list.data[i].r!=0)
		cout<<list.data[i].r<<" "<<list.data[i].e<<" ";
	}
	cout<<endl;

}

// 输入多项式
List InputList()
{
	List list;
	list.len = 0;
	
	int r,e;
	int n;
	
	cin>>n;
	
	while(n--)
	{
		cin>>r>>e;

		list.data[list.len].r = r;
		list.data[list.len].e = e;
		list.len++;
	}
	
	return list; 
}

// 多项式求和
List mul(const List& list1, const List& list2)
{
	//去设出答案链表 
	List list3;
	list3.len=0;
	
	//用i和j两个指针分别指向list1和list2 从而进行遍历
	//1.先去无脑地把所有项都乘一遍 
	int i = 0 , j = 0;
	int l1 = list1.len , l2 = list2.len;
	
	for( int i = 0 ; i<l1 ; i++ )
	{
		for( int j = 0 ; j<l2 ; j++ )
		{
			if(list1.data[i].r)
			list3.data[list3.len].e = list1.data[i].e + list2.data[j].e;
			list3.data[list3.len].r = list1.data[i].r * list2.data[j].r;
			
			if( list3.data[list3.len].r != 0 )	list3.len++;	//如果相乘后系数为0 则不计入list3中,自然也不会加他的长度 
		}
	}
	
	//2.进行排序(降幂排序) 
	int l3 = list3.len;
	
	sort(list3.data,list3.data+l3,cmp);//利用sort让list3.data也为降序排列 
	
	//3.合并同类项 
	if(l3>2)	//特判一下 如果list3中只有一个元素则不用去合并了 
	{
		for(int p=1;i<l3;i++)
      {
         if(list3.data[i].e==list3.data[i-1].e)  //若指数一样就把系数合并
         {
            list3.data[i].r+=list3.data[i-1].r;
            list3.data[i-1].r=0;
         }
      }
	}
	
	
	
	
	return list3;
}

int main()
{
    // freopen("/config/workspace/answer/DataStructure/test.in","r",stdin);    
    List list1 = InputList();
    List list2 = InputList();
    List list = mul(list1, list2);
    PrintList(list);
    return 0;
}

见相乘部分的算法

首先,我们思考一下自己手写计算多项式的步骤。应该是先把两个多项式的每项都相乘(指数和 系数乘),再排序 , 最后合并同类项(指数相同)即可

1.        先用两个指针分别指向list1和list2,去用一个双重for循环无脑地把所有项都相乘一遍

        注意: 此时如果相乘的结果包含了系数为0的项,则不应该计入答案数组中

2.        对list3进行降幂排序(利用sort函数去进行排序)

        要注意我们是要对结构体list3中的结构体数组data【】进行排序,所以传入sort函数的应该是list3.data

3.        降幂排序后,再去合并同类项

        c.      一元多项式的求导(附加代码模式)

一元多项式的求导(附加代码模式)

题目:

        

代码实现:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct  Node
{
    int r;  // 系数
    int e;  // 指数
};

// 线性表存储一元多项式
struct List{
    Node data[10000+5];
    int len;
};

// 输出多项式
void PrintList(const List& list)
{
	//特判一下特殊情况 
	if( list.len==1 && list.data[0].e==0 )
	{
		cout<<"0";
	}
	else
	{
		//去进行遍历输出
    	for (int i = 0; i < list.len; i++) 
		{
        	cout << list.data[i].r << " " << list.data[i].e << " ";
		}
	}
	
    cout << endl;
}

// 输入多项式
List InputList()
{
	//先设出链表(头节点),并进行初始化(使其长度为0) 
    List list;
    list.len = 0;
    
    while (1) 
	{
        int r, e;
        cin >> r >> e;
        
        if (r == -1 && e == -1)	break;	//如果-1 -1 则停止输入,跳出循环 
        
        //正常情况下则把系数与指数输入 
        //注:要与前面的区分好这里的list就只是一个普通的结构体而非结构体指针了 所以不再需要->了 
        list.data[list.len].r = r;
        list.data[list.len].e = e;
        list.len++;
    }
    
    return list;
    
}

// 多项式求导
List getDerivation(const List& list)
{
    List newlist;
    newlist.len = 0;
    
    //特判一下特殊情况 
	if( list.len==1 && list.data[0].e==0 || list.len==0 )
	{
		newlist.data[0].r = list.data[0].r;
        newlist.data[0].e = list.data[0].e;
        newlist.len++;
	}
	
    //遍历进行求导
    //在这里 直接把系数为0的项干掉了 
    for (int i = 0; i < list.len; i++) 
	{
        if (list.data[i].e != 0) 
		{
            newlist.data[newlist.len].r = list.data[i].r * list.data[i].e;
            newlist.data[newlist.len].e = list.data[i].e - 1;
            newlist.len++;
        }
    }
    return newlist;
}

int main(){
    // freopen("/config/workspace/answer/DataStructure/test.in","r",stdin);    
    List list = InputList();
    List newlist = getDerivation(list);
    PrintList(newlist);
    return 0;
}

 进行常规求导操作即可

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值