多项式的余数定理及其应用(C++)

f(x)f(x)f(x) 是一个 NNN 次多项式: f(x)=a0+a1x+⋯+aNxNf(x) = a_0 + a_1 x + \cdots + a_N x^Nf(x)=a0​+a1​x+⋯+aN​xN

那么 f(x)f(x)f(x) 被 (x−c)(x - c)(x−c) 除得到的商等于 f(c)f(c)f(c)。 也就是如果

f(x)=Q(x)(x−c)+rf(x) = Q(x) (x-c) + r \\ f(x)=Q(x)(x−c)+r

那么 :r=f(c)r = f(c)r=f(c)

利用这个定理,可以将计算 f(c)f(c)f(c) 转化为计算 rrr。如果计算 rrr 有快速算法,那么就可以快速计算出 f(c)f(c)f(c)。 下面就来推导如何计算 rrr。

设:
f(x)=∑i=0NaixiQ(x)=∑i=0N−1bixif(x) = \sum_{i=0}^{N} {a_i x^i} \\ Q(x) = \sum_{i=0}^{N-1} {b_i x^i} f(x)=i=0∑N​ai​xiQ(x)=i=0∑N−1​bi​xi

那么有:
∑i=0Naixi=(x−c)∑i=0N−1bixi+r=bN−1xN+∑i=1N−1(bi−1−cbi)xi−b0c+r\sum_{i=0}^{N} {a_i x^i} = (x -c)\sum_{i=0}^{N-1} {b_i x^i} + r \\ = b_{N-1} x^N + \sum_{i=1}^{N-1} {(b_{i-1} - c b_i) x^{i} } - b_0 c + r i=0∑N​ai​xi=(x−c)i=0∑N−1​bi​xi+r=bN−1​xN+i=1∑N−1​(bi−1​−cbi​)xi−b0​c+r

两边同幂次的项相等:
aN=bN−1ai=bi−1−cbi,(i=1,2,⋯N−1)a0=−cb0+ra_N = b_{N-1} \\ a_i = b_{i -1} - c b_i, (i = 1, 2, \cdots N-1 )\\ a_0 = - c b_0 + r aN​=bN−1​ai​=bi−1​−cbi​,(i=1,2,⋯N−1)a0​=−cb0​+r

所以:

bN−1=aNbi=ai+1+cbi+1r=a0+cb0b_{N-1} = a_N\\ b_i = a_{i+1} + c b_{i+1} \\ r = a_0 + c b_0 bN−1​=aN​bi​=ai+1​+cbi+1​r=a0​+cb0​

了解多项式的 Horner 公式的人可能会发现,这里的公式怎么和 Horner 公式几乎一样。确实,这里其实就是 Horner 公式的另一种解释方法。

按照这个思路我们就可以写个 C 函数。

/*** @brief polydiv 计算 p(x) / (x - a) 的商和余数* @param p 多项式的系数,p0 .. pn* @param n 多项式的次数* @param q 结果返回 r, q0, q1, ... qn-1 ,注意第一个数是余数* @return 返回的也是余数,也等于 p(a) 的值*/
double polydiv(double p[], int n, double a, double q[])
{q[n] = p[n];for(int i = n - 1; i >= 0; i--){q[i] = p[i] + a * q[i+1];}return q[0];
}

当然,如果我们不需要返回 q[],可以简化为:

/*** @brief polyeval 利用 Horner 公式计算多项式的值* @param p 多项式的系数 a0, a1, a2,\cdots a_n* @param n 多项式的次数 n* @param x 要计算的值* @return 返回多项式在 x 点的值*/
double polyeval(double p[], int n, double x)
{double r = 0;while (n >= 0){r = p[n] + r * x;n--;}return r;
}

实际上,我们还可以更进一步,考虑另一个问题。
f(x)f(x)f(x) 是一个 NNN 次多项式: f(x)=a0+a1x+⋯+aNxNf(x) = a_0 + a_1 x + \cdots + a_N x^Nf(x)=a0​+a1​x+⋯+aN​xN

有时我们需要将它变换为另一个等价的多项式 q(x)=b0+b1(x−c)+⋯+bN(x−c)Nq(x) = b_0 + b_1 (x-c) + \cdots + b_N (x-c)^Nq(x)=b0​+b1​(x−c)+⋯+bN​(x−c)N

那么如何通过 a0,a1,⋯ ,aNa_0, a_1, \cdots , a_Na0​,a1​,⋯,aN​ 来得到 b0,b1,⋯ ,bNb_0, b_1, \cdots , b_Nb0​,b1​,⋯,bN​。

我们同样设:
f(x)=Q1(x)(x−c)+r0f(x) = Q_1(x) (x-c) + r_0 \\ f(x)=Q1​(x)(x−c)+r0​

把 x=cx = cx=c 带入,可以很容易验证 b0=f(c)=r0b_0 = f(c) = r_0b0​=f(c)=r0​

再继续设:
Q1(x)=Q2(x)(x−c)+r1Q_1(x) = Q_2(x) (x-c) + r_1 \\ Q1​(x)=Q2​(x)(x−c)+r1​

同样的方法可以验证:b1=Q1(c)=r1b_1 = Q_1(c) = r_1b1​=Q1​(c)=r1​

这个过程反复做下去就可以依次得到 b0,b1,⋯ ,bNb_0, b_1, \cdots , b_{N}b0​,b1​,⋯,bN​

这个计算过程张,系数的变化如下:

a0,a1,a2,a3,a4,⋯ ,aNr0,b0,b1,b2,b3,⋯ ,bN−1r0,r1,c0,c1,c2,⋯ ,cN−2r0,r1,r2,d0,d1,⋯ ,dN−3⋯r0,r1,r2,r3,r4,⋯ ,rNa_0, a_1, a_2, a_3, a_4, \cdots , a_N \\ r_0, b_0, b_1, b_2, b_3, \cdots, b_{N-1} \\ r_0, r_1, c_0, c_1, c_2, \cdots, c_{N-2} \\ r_0, r_1, r_2, d_0, d_1, \cdots, d_{N-3} \\ \cdots \\ r_0, r_1, r_2, r_3, r_4, \cdots, r_N a0​,a1​,a2​,a3​,a4​,⋯,aN​r0​,b0​,b1​,b2​,b3​,⋯,bN−1​r0​,r1​,c0​,c1​,c2​,⋯,cN−2​r0​,r1​,r2​,d0​,d1​,⋯,dN−3​⋯r0​,r1​,r2​,r3​,r4​,⋯,rN​

为了实现这个过程,我们需要对刚刚写的 polydiv 函数做些修改,让它在原位修改各个系数的值。

/*** @brief polydiv2 计算 p(x) / (x - a) 的除数和余数。* @param p 多项式的系数,p0 .. pn,同时计算结束后也返回 r, q0, q1, ... qn-1* @param n 多项式的次数* @param a* @return 返回的也是余数,也等于 p(a) 的值*/
double polydiv2(double p[], int n, double a)
{for(int i = n - 1; i >= 0; i--){p[i] = p[i] + a * p[i+1];}return p[0];
}/*** @brief polyshift 将 x 的多项式变换为 (x-a) 的多项式* @param p 多项式的系数,p0 .. pn, 计算结束后返回新的系数* @param n 多项式的次数* @param a 将  (x - a)*/
void polyshift(double p[], int n, double a)
{for(int i = n; i >= 1; i--){polydiv2(p, i, a);p++;}
}

下面是个测试用例:

有一个多项式:f(x)=1+2x+3x2+4x3+5x4+6x5f(x) = 1 +2 x + 3 x^2 + 4 x^3 + 5 x^4 + 6 x^5f(x)=1+2x+3x2+4x3+5x4+6x5
将其变换为 (x−5.5)(x- 5.5)(x−5.5) 的形式,用 Mathematica 可以算出是:
f(x)=35540.6+31177.4(x−5.5)+10959(x−5.5)2+1929(x−5.5)3+170(x−5.5)4+6(x−5.5)5f(x) = 35540.6 + 31177.4 (x-5.5) + 10959 (x-5.5)^2 + 1929 (x-5.5)^3 + 170 (x-5.5)^4 + 6 (x-5.5)^5 f(x)=35540.6+31177.4(x−5.5)+10959(x−5.5)2+1929(x−5.5)3+170(x−5.5)4+6(x−5.5)5

Mathematica 的代码如下:

p = 1 + 2 x + 3 x^2 + 4 x^3 + 5 x^4 + 6 x^5
Expand[p /. {x -> y + 5.5}] /. {y -> x - 5.5}

C++ 的验证代码如下:

    double ax[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};polyshift(ax, 5, 5.5);for(int i = 0; i <= 5; i++){std::cout << ax[i] << std::endl;}

计算结果如下:

35540.6
31177.4
10959
1929
170
6

说明这个代码是正确的。
至此,这个问题就算是比较圆满的解决了。

多项式的余数定理及其应用相关推荐

  1. 高等代数 多项式环(第7章)3 一元多项式的根与不可约多项式

    一.一元多项式的根与复数域上的不可约多项式(7.6) 1.一元多项式的一次因式 (1)余数定理: 定理1:在K[x]K[x]K[x]中,用x−ax-ax−a去除f(x)f(x)f(x)所得的余式是f( ...

  2. 小蓝本 第一本 《因式分解技巧》 第八章 多项式的一次因式 笔记 (第八天)

    小蓝本 第一本 <因式分解技巧> 第八章 多项式的一次因式 笔记 (第八天) 前言 余数定理 有理根求法 第一步 第二步(可能有理根多的情况下,可以用) 第三步 快速识别特殊有理根 情况1 ...

  3. 【转载与整理】多项式除法与综合除法

    一.一般多项式除法 二.综合除法(一般多项式除以形如x-a的多项式) 非常好证明,除了最高次项,被除式的每一项系数都可以被分解为两部分,x*商的较低一项.a*商的同次项. 因此用[被除式的第i项系数] ...

  4. 算法学习笔记--余数定理

    tips:算法学习过程中,总是会遇到许多有趣的知识,当前的数学理论几乎西方数学理论所统治,但在学习的过程经常会发现我华夏先祖也曾拥有独特的思考.与西方文明喜欢用晦涩的特殊符号进行理论推导所不同的是,华 ...

  5. pat 多项式A/B

    第一次接触多项式除法 cccc L2-018. 多项式A除以B 2017-04-01 09:09 9人阅读 评论(0) 收藏 举报  分类: 数学(30)  模拟(4)  目录(?)[+] 点击打开链 ...

  6. matlab两个多项式相除,C++和MATLAB混合编程求解多项式系数(矩阵相除)

    摘要:MATLAB对于矩阵处理是非常高效的,而C++对于矩阵操作是非常麻烦的,因而可以采用C++与MATLAB混合编程求解矩阵问题. 主要思路就是,在MATLAB中编写函数脚本并使用C++编译为dll ...

  7. 【点云重采样Resampling】Python-pcl 基于多项式平滑点云及法线估计的曲面重建

    1. 点云重采样 基于多项式平滑点云及法线估计的曲面重建以实现重采样,可以使得点云数据更规整一些,没之前那么杂乱. set_Compute_Normals(True) 可以通过在最小二乘法中进行法线估 ...

  8. 【机器学习入门】(3) 朴素贝叶斯算法:多项式、高斯、伯努利,实例应用(心脏病预测)附python完整代码及数据集

    各位同学好,今天我和大家分享一下朴素贝叶斯算法中的三大模型.在上一篇文章中,我介绍了朴素贝叶斯算法的原理,并利用多项式模型进行了文本分类预测. 朴素贝叶斯算法 -- 原理,多项式模型文档分类预测,附p ...

  9. 基础数据结构【四】————环形链表与多项式

    主要演示环形列表节点的创建插入, 删除,遍历,环形链表连接 .双向链表节点的建立与插入 ,双向链表中节点的删除 以及环形链表在多项式中的应用 DEMO1:环形链表节点的创建与插入 /* [名称]:ch ...

最新文章

  1. 软件测试培训分享:如何划分bug的严重级别
  2. .net程序员使用Oracle新手上路指南
  3. 牛津大学入学面试就这?组队选个颜色?背后的逻辑水深得很
  4. salt stack 工具之一——远程命令
  5. 怎么从gitlab上下载别人的代码
  6. js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝
  7. 图神经网络的可解释性
  8. Vue传递方法给页面调用
  9. poi 和jxl导出excel(2)
  10. 中班音乐活动 机器人_幼儿园大班音乐活动教案:《机器人》
  11. 好书推荐_Windows程序设计(第五版)
  12. 电磁流量计 ADMAG AXG系列
  13. c语言水仙花数pow,c语言如何解水仙花数
  14. 谷歌 发布android 8,2017谷歌大会正式发布Android 8.0!
  15. Python可视化-WordCloud生成云词图片
  16. 【软考-中级】系统集成项目管理工程师-【3信息系统集成专业技术知识】
  17. msvcr120.dll丢失如何修复
  18. 汕尾督办pc端和移动端
  19. 何炅谢娜刘诗诗杨幂黄晓明 明星最新片酬曝光
  20. Sql链接数据库基本语法

热门文章

  1. 比Linken Sphere(林肯法球)更多更新浏览器指纹的国产防关联工具-VMLogin中文版
  2. mysql 生成id函数_MySQL ID生成策略
  3. C++模拟手机调查问卷
  4. ens天空盒_这句话的意思
  5. 华为天猫官方旗舰店粉丝突破一千万
  6. 不要签名证书将网页打包封装成苹果APP,无需苹果企业签名,IPA证书签名,ios签名证书,免越狱安装...
  7. Java 3种批量插入更新操作的效率横向比较
  8. CSS布局示例 1 - 页面色块布局
  9. 【虹科讲座预告】企业如何防止基于USB的数据外泄
  10. java if 跳出循环_break跳出的是if语句,还是for循环?