C语言求多项式乘法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言求多项式乘法相关的知识,希望对你有一定的参考价值。

多项式乘法的实现,已知如下两个多项式
P(x)=P X + P X +...+ P X+P
Q(x)=q X +q X +...+q X+q
求它们的乘积多项式 S(x)=s X +...+s X+s 。
可以定义两个一维数组p,q,按照次数从高到低存储两个多项式的系数,定义一维数组来s来存储结果;利用函数来完成对结果多项式各项系数的计算,最后在屏幕上计算结果。
要怎么做啊,谢谢求解

/*
* 文件名: 1_3.c(选做题)
* 实验环境: Turbo C 2.0
* 完成时间: 2003年2月22日
*--------------------------------------------------------------------
* 改进说明: 可以实现多个多项式的加法、减法、乘法,并且比书中算法更加
* 合理. 例如: 连加a+b+c+d,连减a-b-c-d,连乘a*b*c*d.
*/

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

#define TRUE 1
#define FALSE 0
#define POSITIVE 1
#define NEGATIVE -1

typedef int status;
typedef struct NodeType

float fCoeff;
int iExpon;
struct NodeType *next;
NodeType, *LinkType;
typedef LinkType polynomial;
typedef polynomial *PolyPointer;

status MakePolyBuff(PolyPointer *, const int);
status MakeNode(polynomial *, const float, const int);
void AppNodeToList(polynomial *, polynomial); /* 在链表尾追加结点 */
status CreatePolyn(PolyPointer, int);
status ProcStrError(const char[]); /* 检查输入的数据 */
void SortPolyn(PolyPointer, int); /* 根据iExpon域对链表进行升序排序 */
void DestroyBuff(PolyPointer, const int);
void DestroyPolyn(polynomial);
int PolynLength(const polynomial); /* 求链表的长度 */
void AddProcess(PolyPointer, const int, PolyPointer, const int);
void SubstractProcess(PolyPointer, const int, PolyPointer);
void MultiplyProcess(PolyPointer, const int, PolyPointer);
void PrintPolyn(const polynomial);
void MergePolynCoeff(PolyPointer, int); /* 在有序链表中,合并同类项 */

int main(void)

int iCounter,
iPolyNum; /* 多项式链表缓冲区中链表的个数 */
PolyPointer PolyBuff = NULL; /* 用户输入的多项式链表缓冲区 */
polynomial PolyAddRes = NULL, /* 存放连加结果链表 */
PolySubRes = NULL, /* 存放连减结果链表 */
PolyMulRes = NULL; /* 存放连乘结果链表 */
char strNum[10];

do

printf("请输入需要构造多项式的个数,至少2个: ");
gets(strNum);
iPolyNum = atoi(strNum);
while (iPolyNum < 2);

MakePolyBuff(&PolyBuff, iPolyNum);
CreatePolyn(PolyBuff, iPolyNum);
SortPolyn(PolyBuff, iPolyNum);
MergePolynCoeff(PolyBuff, iPolyNum);
printf("\n打印用户输入并整合后的多项式:\n");
for (iCounter = 0; iCounter < iPolyNum; iCounter++)

printf("第%d个项式:\n", iCounter + 1);
PrintPolyn(*(PolyBuff + iCounter));


AddProcess(PolyBuff, iPolyNum, &PolyAddRes, POSITIVE);
printf("\n----------------连加结果-----------------\n");
PrintPolyn(PolyAddRes);

SubstractProcess(PolyBuff, iPolyNum, &PolySubRes);
printf("\n----------------连减结果-----------------\n");
PrintPolyn(PolySubRes);

MultiplyProcess(PolyBuff, iPolyNum, &PolyMulRes);
printf("\n----------------连乘结果-----------------\n");
PrintPolyn(PolyMulRes);

printf("\n运行完毕!\n");
/* 回收资源 */
DestroyBuff(PolyBuff, iPolyNum);
DestroyPolyn(PolyAddRes);
DestroyPolyn(PolySubRes);
DestroyPolyn(PolyMulRes);

getch();
return 0;


status MakePolyBuff(PolyPointer *polyBuffHead, const int iPolyNum)

int iCounter;

*polyBuffHead = (PolyPointer)
malloc(sizeof(polynomial) * iPolyNum);
if (!(*polyBuffHead))

printf("错误,内存溢出!\n");
return FALSE;

for (iCounter = 0; iCounter < iPolyNum; iCounter++)
*(*polyBuffHead + iCounter) = NULL;

return TRUE;


status CreatePolyn(PolyPointer PolyBuff, int iPolyNum)

int iCounter, iExpon;
float fCoeff;
char strNum[100], strTemp[64], *cpCurr, *cpCurrNum;
polynomial pNewNode = NULL, pInsPos = NULL;

printf("\n请输入构造多项式的系数和指数...\n");
printf("输入一个多项式的方式为: 系数, 指数; ... ; 系数, 指数;\n例如: 3, 4; 5, 6; 7, 8;\n");
for (iCounter = 0; iCounter < iPolyNum; iCounter++)

printf("\n请输入第%d个多项式:\n", iCounter + 1);
gets(strNum);
if(!ProcStrError(strNum)) return FALSE;
cpCurr = cpCurrNum = strNum;
while (*cpCurr != '\0')

if (*cpCurr == ',')

strncpy(strTemp, cpCurrNum, cpCurr - cpCurrNum);
strTemp[cpCurr - cpCurrNum] = '\0';
fCoeff = (float)atof(strTemp);
cpCurrNum = cpCurr + 1;

else if (*cpCurr == ';')

strncpy(strTemp, cpCurrNum, cpCurr - cpCurrNum);
strTemp[cpCurr - cpCurrNum] = '\0';
iExpon = atoi(strTemp);
MakeNode(&pNewNode, fCoeff, iExpon);
AppNodeToList(PolyBuff + iCounter, pNewNode);
cpCurrNum = cpCurr + 1;

cpCurr++;



return TRUE;


status MakeNode(LinkType *pp, const float coeff, const int expon)

if (!(*pp = (LinkType)malloc(sizeof(NodeType) * 1)))

printf("Error, the memory is overflow!\n");
return FALSE;

(*pp)->fCoeff = coeff;
(*pp)->iExpon = expon;
(*pp)->next = NULL;

return TRUE;


void AppNodeToList(polynomial *pHead, polynomial pNewNode)

static polynomial pCurrNode;

if (!(*pHead))
(*pHead) = pCurrNode = pNewNode;
else

pCurrNode->next = pNewNode;
pCurrNode = pCurrNode->next;



void SortPolyn(PolyPointer PolyBuff, int iPolyNum)

int iCounter;
polynomial pTemp, pTempCurrNode, /* 临时链表 */
pPrevMinExp, pCurrMinExp,/* 指向最小iExpon结点的指针 */
pCurrNode, pPrevNode;

for (iCounter = 0; iCounter < iPolyNum; iCounter++)

pTemp = NULL;
while (*(PolyBuff + iCounter) != NULL)

pPrevNode = pPrevMinExp = pCurrMinExp =
*(PolyBuff + iCounter);
pCurrNode = (*(PolyBuff + iCounter))->next;
while (pCurrNode != NULL)

if (pCurrMinExp->iExpon > pCurrNode->iExpon)

pPrevMinExp = pPrevNode;
pCurrMinExp = pCurrNode;

pPrevNode = pCurrNode;
pCurrNode = pCurrNode->next;

/* 将系数最小的结点从原链表中取出 */
if (pCurrMinExp == *(PolyBuff + iCounter))
*(PolyBuff + iCounter) = pPrevMinExp->next;
else
pPrevMinExp->next = pCurrMinExp->next;
/* 将系数最小的结点插入升序链表 */
pCurrMinExp->next = NULL;
if (!pTemp)
pTemp = pTempCurrNode = pCurrMinExp;
else

pTempCurrNode->next = pCurrMinExp;
pTempCurrNode = pTempCurrNode->next;



*(PolyBuff + iCounter) = pTemp;



void MergePolynCoeff(PolyPointer PolyBuff, int iPolyNum)

int iCounter;
float MergeCoeffRes = 0;
polynomial TempList, ResList = NULL, pCurrNode, pPreNode,
pNewNode = NULL;

for (iCounter = 0; iCounter < iPolyNum; iCounter++)

pPreNode = TempList= *(PolyBuff + iCounter);
MergeCoeffRes = pPreNode->fCoeff;
pCurrNode = (*(PolyBuff + iCounter))->next;
while (pCurrNode != NULL)

while ((pCurrNode != NULL) &&
(pCurrNode->iExpon == pPreNode->iExpon))

MergeCoeffRes += pCurrNode->fCoeff;
pPreNode = pCurrNode;
pCurrNode = pCurrNode->next;


/* 在ResList中加入新结点 */
if (MergeCoeffRes != 0)

MakeNode(&pNewNode, MergeCoeffRes, pPreNode->iExpon);
AppNodeToList(&ResList, pNewNode);
MergeCoeffRes = 0;


pPreNode = pCurrNode;


DestroyPolyn(TempList);
*(PolyBuff + iCounter) = ResList;
ResList = NULL;




void AddProcess(PolyPointer polyBuff, const int iPolyNum,
PolyPointer pResult, const int iSign)

int iCounter;
float fCoeffRes;
polynomial pNewNode, pCurrNode_1, pCurrNode_2,
pDelList = NULL, /* 下次要删除的中间结果链表 */
pResList = NULL; /* 中间结果链表 */

pCurrNode_1 = *(polyBuff);
for (iCounter = 1; iCounter < iPolyNum; iCounter++)

pCurrNode_2 = *(polyBuff + iCounter);
while (pCurrNode_1 != NULL && pCurrNode_2 != NULL)

if (pCurrNode_1->iExpon == pCurrNode_2->iExpon)

fCoeffRes = 0;
fCoeffRes = pCurrNode_1->fCoeff +
iSign * pCurrNode_2->fCoeff;
if (fCoeffRes != 0)

MakeNode(&pNewNode, fCoeffRes,
pCurrNode_1->iExpon);
AppNodeToList(&pResList, pNewNode);

pCurrNode_1 = pCurrNode_1->next;
pCurrNode_2 = pCurrNode_2->next;

else if (pCurrNode_1->iExpon < pCurrNode_2->iExpon)

MakeNode(&pNewNode, pCurrNode_1->fCoeff,
pCurrNode_1->iExpon);
AppNodeToList(&pResList, pNewNode);
pCurrNode_1 = pCurrNode_1->next;

else /* 当pCurrNode_1->iExpon > pCurrNode_2->iExpon时候 */

MakeNode(&pNewNode, iSign * pCurrNode_2->fCoeff,
pCurrNode_2->iExpon);
AppNodeToList(&pResList, pNewNode);
pCurrNode_2 = pCurrNode_2->next;


/* 加入余下的多项式 */
while (pCurrNode_1 != NULL)

MakeNode(&pNewNode, pCurrNode_1->fCoeff,
pCurrNode_1->iExpon);
AppNodeToList(&pResList, pNewNode);
pCurrNode_1 = pCurrNode_1->next;

while (pCurrNode_2 != NULL)

MakeNode(&pNewNode, iSign * pCurrNode_2->fCoeff,
pCurrNode_2->iExpon);
AppNodeToList(&pResList, pNewNode);
pCurrNode_2 = pCurrNode_2->next;


if (pDelList != NULL) DestroyPolyn(pDelList);
pCurrNode_1 = pResList;
pDelList = pResList;
pResList = NULL;


*pResult = pCurrNode_1;


void SubstractProcess(PolyPointer polyBuff, const int iPolyNum,
PolyPointer pResult)

AddProcess(polyBuff, iPolyNum, pResult , NEGATIVE);


void MultiplyProcess(PolyPointer polyBuff, const int iPolyNum,
PolyPointer pResult)

int iCounter = 1, jCounter = 0, iLength; /* 缓冲区的长度 */
PolyPointer pTemPBuff = NULL; /* 存放中间结果的缓冲区 */
polynomial pCurrNode_1, pCurrNode_2, pNewNode = NULL;

/* 初始化 */
pCurrNode_1 = polyBuff[0];
iLength = PolynLength(polyBuff[0]);
MakePolyBuff(&pTempBuff, iLength);
while (TRUE)

while (pCurrNode_1 != NULL)

pCurrNode_2 = polyBuff[iCounter];
while (pCurrNode_2 != NULL)

MakeNode(&pNewNode,
pCurrNode_1->fCoeff * pCurrNode_2->fCoeff,
pCurrNode_1->iExpon + pCurrNode_2->iExpon);
AppNodeToList(&pTempBuff[jCounter], pNewNode);
pCurrNode_2 = pCurrNode_2->next;

jCounter++;
pCurrNode_1 = pCurrNode_1->next;


/* 回收旧的中间结果 */
if (pResult != NULL) DestroyPolyn(*pResult);
/* 获得新的中间结果 */
AddProcess(pTempBuff, iLength, pResult , POSITIVE);
DestroyBuff(pTempBuff, iLength); /* 回收存中间结果的缓冲区 */
jCounter = 0;
if (++iCounter >= iPolyNum)
break;
else

iLength = PolynLength(*pResult);
MakePolyBuff(&pTempBuff, iLength);
pCurrNode_1 = *pResult;




void PrintPolyn(const polynomial polyList)

polynomial pCurrNode = polyList;

printf("多项式的长度为: %d\n", PolynLength(polyList));
while (pCurrNode != NULL)

printf("%.2fX^%d", pCurrNode->fCoeff, pCurrNode->iExpon);
if (pCurrNode->next != NULL)
if (pCurrNode->next->fCoeff > 0 )
printf("+");
pCurrNode = pCurrNode->next;

printf("\n");


int PolynLength(const polynomial polyList)

int iLength = 0;
polynomial pCurrNode = polyList;

while (pCurrNode != NULL)

pCurrNode = pCurrNode->next;
iLength++;

return iLength;


void DestroyBuff(PolyPointer polyBuff, const int iPolyNum)

int iCounter;

for (iCounter = 0; iCounter < iPolyNum; iCounter++)
DestroyPolyn(polyBuff[iCounter]);
free(polyBuff);


void DestroyPolyn(polynomial polyList)

polynomial pCurrNode;

while (polyList != NULL)

pCurrNode = polyList;
polyList = polyList->next;
free(pCurrNode);



status ProcStrError(const char str[])

const char *cpCurr = str;

if (!strlen(str))

printf("你没有输入数据!\n");
return FALSE;

while (*cpCurr != '\0')

if (!(*cpCurr == ' ' || *cpCurr == ',' || *cpCurr == ';'
|| *cpCurr == '-')
&& ('0' > *cpCurr || *cpCurr > '9')
|| (*(cpCurr + 1) == '\0' && *cpCurr != ';'))

printf("输入数据出错,请注意正确的输入方式!\n");
return FALSE;

cpCurr++;


return TRUE
参考技术A #include <stdio.h>
main()

int i,x,a,n,result=1;
printf("Please input x & a & n \n");
scanf("%d,%d,%d",&x,&a,&n);
for(i=1;i<=n;i++)

result=x+a^i;
result *= result;

printf("Result is %d",result);
参考技术B 广告歌

●UOJ 34 多项式乘法

题链:

http://uoj.ac/problem/34

题解:

FFT入门题。

(终于接触到迷一样的FFT了)

初学者在对复数和单位根有简单了解的基础上,可以直接看《再探快速傅里叶变换》(毛啸)

(主要用于求两个序列的卷积)

代码:

递归版:

#include<bits/stdc++.h>
#define MAXN 300000
using namespace std;
const double Pi=acos(-1);
struct Z{
	double real,image;
	Z(double _real=0,double _image=0):real(_real),image(_image){}
	Z operator - ()const {return Z(-real,-image);}
	friend Z operator + (const Z &A,const Z &B){return Z(A.real+B.real,A.image+B.image);};
	friend Z operator - (const Z &A,const Z &B){return A+(-B);}
	friend Z operator * (const Z &A,const Z &B){return Z(A.real*B.real-A.image*B.image,A.image*B.real+A.real*B.image);}
};
void FFT(int n,Z *Y,int sn){
	if(n==1) return;
	Z L[n>>1],R[n>>1];
	for(int k=0;k<n;k+=2)
		L[k>>1]=Y[k],R[k>>1]=Y[k+1];
	FFT(n/2,L,sn); FFT(n/2,R,sn);
	Z dw=Z(cos(2*Pi/n),sin(sn*2*Pi/n)),w=Z(1,0),tmp;
	for(int k=0;k<n/2;k++,w=w*dw)
		tmp=w*R[k],Y[k]=L[k]+tmp,Y[k+n/2]=L[k]-tmp;
}
int main(){
	static Z A[MAXN],B[MAXN];
	int n,m; scanf("%d%d",&n,&m); n++; m++;
	for(int i=0,x;i<n;i++) scanf("%d",&x),A[i]=Z(x,0);
	for(int i=0,x;i<m;i++) scanf("%d",&x),B[i]=Z(x,0);
	m=n+m-1; for(n=1;n<m;n<<=1);
	FFT(n,A,1); FFT(n,B,1);
	for(int i=0;i<n;i++) A[i]=A[i]*B[i];
	FFT(n,A,-1);
	for(int i=0;i<m;i++) printf("%d ",(int)(A[i].real/n+0.5));
	return 0;
}

  

非递归版:

 

#include<bits/stdc++.h>
#define MAXN 300000
using namespace std;
const double Pi=acos(-1);
struct Z{
	double real,image;
	Z(double _real=0,double _image=0):real(_real),image(_image){}
	Z operator - ()const {return Z(-real,-image);}
	friend Z operator + (const Z &A,const Z &B){return Z(A.real+B.real,A.image+B.image);};
	friend Z operator - (const Z &A,const Z &B){return A+(-B);}
	friend Z operator * (const Z &A,const Z &B){return Z(A.real*B.real-A.image*B.image,A.image*B.real+A.real*B.image);}
};
int order[MAXN];
void FFT(int n,Z *Y,int sn){
	for(int i=0;i<n;i++) if(i<order[i]) swap(Y[i],Y[order[i]]);
	for(int d=2;d<=n;d<<=1){
		Z dw=Z(cos(2*Pi/d),sin(sn*2*Pi/d)),w,tmp;
		for(int i=0;w=Z(1,0),i<n;i+=d)
			for(int k=i;k<i+d/2;k++,w=w*dw)
				tmp=w*Y[k+d/2],Y[k+d/2]=Y[k]-tmp,Y[k]=Y[k]+tmp;
	}
}
int main(){
	static Z A[MAXN],B[MAXN];
	int n,m,len; scanf("%d%d",&n,&m); n++; m++;
	for(int i=0,x;i<n;i++) scanf("%d",&x),A[i]=Z(x,0);
	for(int i=0,x;i<m;i++) scanf("%d",&x),B[i]=Z(x,0);
	m=n+m-1; for(len=0,n=1;n<m;n<<=1) len++;
	for(int i=1;i<n;i++) order[i]=(order[i>>1]>>1)|((i&1)<<(len-1));
	FFT(n,A,1); FFT(n,B,1);
	for(int i=0;i<n;i++) A[i]=A[i]*B[i];
	FFT(n,A,-1);
	for(int i=0;i<m;i++) printf("%d ",(int)(A[i].real/n+0.5));
	return 0;
}

 

  

 

以上是关于C语言求多项式乘法的主要内容,如果未能解决你的问题,请参考以下文章

c++编程 多项式的乘法

FFT求卷积(多项式乘法)

数字信号处理卷积编程实现 ( Matlab 卷积和多项式乘法 conv 函数 | 使用 matlab 代码求卷积并绘图 )

[HDU4609] 3-idiots - 多项式乘法,FFT

python中这个算法该怎么解释?求大神支招。

多项式的高级运算