作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
**这是一种以相当古老的语言标准ML实现的算法。我很难理解此算法:
fun polyquotremd ts ((n,b) :: us) =
let fun quo [] qs = (rev qs, [])
| quo ((m,a) :: ts) qs =
if m < n then (rev qs, (m,a) :: ts)
else
quo (polysum ts
(map (termproduct(m-n, ~a/b)) us))
((m-n, a/b) :: qs)
in
quo ts []
end;
[(2, 1.0), (0, 1.0)]
。这由类型
(int*real)list
给出,如下面的辅助函数所示。我们想要获得一个输出
(quo, rem)
,每个输出都是分别表示商和余数的元组列表。
ts
是要除的多项式,而
us
是除数。
ts = []
意味着我们没有多项式可除,那么我们返回qs,即我们的商数结果作为答案。由于我们一直在qs列表的开头添加
((m-n, a/b) :: qs)
,因此我们需要反转列表以使列表以最大的指数开头。
(rev qs, (m,a) :: ts)
,即
(quo, rem)
((m-n, a/b) :: qs)
是我们要添加的累积结果,但是
polysum ts (map (termproduct(m-n, ~a/b)) us))
实际在做什么?这背后的数学是什么?
~a/b
(供您参考,表示
-a/b
)。
fun take ([], _) = []
| take (x::xs, i) = if i>0
then x :: take(xs, i-1)
else [];
fun drop ([], _) = []
| drop (x::xs, i) = if i>0 then drop(xs,i-1)
else x::xs;
fun termproduct (m,a) (n,b) = (m+n, a*b) : (int*real);
fun polyproduct [] us = []
| polyproduct [(m,a)] us = map (termproduct(m,a)) us
| polyproduct ts us =
let
val k = length ts div 2
in
polysum (polyproduct (take(ts,k)) us)
(polyproduct (drop(ts,k)) us)
end;
最佳答案
我认为您当前的理解大部分是正确的,而且我不确定您在else
分支中到底不了解什么。
基本思想和不变性
为了避免混淆名称阴影,让ts0
为传递给ts
的polyquotremd
的值,并且us0
= ((n,b) :: us)
。然后对于递归的每个步骤中从外部上下文捕获的quo ts qs
的us0
,除了最后一个,即由返回quo [] qs = (rev qs, [])
和if m < n then (rev qs, (m,a) :: ts)
分支处理的qs
,以下不变式成立
ts0 = us0 * rev qs + ts
ts
)中产生下一项,而新的
ts
具有较低的最高幂,表示该除法运算的其余部分。显然,如果我们可以通过此过程降低
m
的最高功率,使其最高功率
us0
小于
n
最高功率
qs
,那么我们在
ts
和
ts
中有完整的答案。因此,现在我们要做的就是降低
((m,a) :: ts)
的最大功耗。我们将得到的只是标准的
long division算法。
((n,b) :: us)
和除数
(m,a)
,即对于
(n,b)
和
m < n
,检查是否为
(m,a)
。如果是,请完成算法。
(n,b)
除以
(m-n, -a/b)
并找到它们的商。显然是
(map (termproduct(m-n, a/b)) ((n,b) :: us)))
map
。请注意,这不是您的代码所在的行。请稍等,我们也会到达那里。
(termproduct(m-n, a/b))
是一个经典的高阶函数,它接受另一个函数和一个集合,并返回相同大小的新集合,其中每个元素都是对该函数应用相应结果的结果源元素。现在
termproduct
称为
partial application:它接受两个参数
(m-n, a/b)
的函数,并产生一个新参数的函数,其中一个参数(原始函数中的第二个)的第一个参数固定为
((n,b) :: us)
的值。因此,整个构造如下:将
us
的每一项(或代码中的
(m-n, a/b)
)乘以
-1
。显然,这只是将多项式乘以一个项的一种方法。
(m-n, a/b)
来用总和代替该减法。所以现在是
(polysum ((m,a) :: ts)
(map (termproduct(m-n, ~a/b)) ((n,b) :: us)))
(polysum ts
(map (termproduct(m-n, ~a/b)) us))
rev qs
的商/乘数添加到我们的结果多项式中。唯一的次要问题是我们以相反的顺序填写它,即我们首先找到最高的术语,然后找到下一个,依此类推。在纸上可以正常工作,但ML中的列表以相反的顺序填充。这就是为什么我们的两个“出口”分支都在其中包含
quo
的原因。
termproduct (m-n, ~a/b) (n,b)
的另一递归。
(m-n + n, ~a/b*b)
的结果是什么?显然,它是
(m, -a)
=
ts
。因此,这与
(m-n, ~a/b)
中的最高术语完全相反。
2*x^2 + 3*x + 4
的唯一目的是抵消了它们。看来您没有得到我在“基本概念和不变式”部分中描述的内容,而且我不确定是否可以用其他方式重述,但我会尽力而为。除法可以看作是多次相减,而我们却做了几次。如果我们这样看,很显然,我们应该尝试减去除数的一些乘数,以抵消除数的最高项。
x^2 + x + 1
除以
2*x^2
。如果要删除
2
项,则必须将除数乘以
2
,然后减去。因此结果是商=
2*x^2 + 3*x + 4 - 2*(x^2 + x + 1)
,其余为
x + 2
=
2*x^2 + 3*x + 4
。
x^2 + 2*x + 3
除以
2
。请注意,尽管除数不同于之前的示例,但我们仍然必须将其乘以
2
才能去除股息中的最高项。这是因为确定乘数的唯一因素是最高期限的比率。其他不合理的术语会影响最终结果(其余),但不会影响当前结果。请注意,结果仍然是商=
2*x^2 + 3*x + 4 - 2*(x^2 + 2*x + 3)
,但其余部分是
-x - 2
=
2*x^3+3*x^2
x+1
除以
x+2
和
x^3
来观察差异。请注意,要取消
2*x^3/x
,我们的第一个乘数(即商中的最高项)在两种情况下均应相同
2*x^2
=
x+1
x+2
x+1: 2*x^3+3*x^2 = 2*x^2*(x+1) + (2*x^3+3*x^2) - 2*x^2*(x+1) = 2*x^2*(x+1) + x^2
+x^2
同样:
x+2: 2*x^3+3*x^2 = 2*x^2*(x+2) + (2*x^3+3*x^2) - 2*x^2*(x+2) = 2*x^2*(x+2) - x^2
x+1
使用不同的中间休息
-x^2
,对于
x+2
使用不同的中间休息。这意味着下一个乘数将是
+x^2/x
=
+x
和
-x^2/x
=
-x
x+1: 2*x^3+3*x^2 = (2*x^2+x)*(x+1) + x^2 - x*(x+1) = (2*x^2+x)*(x+1) - x
x+2: 2*x^3+3*x^2 = (2*x^2-x)*(x+2) - x^2 - (-x)*(x+2) = (2*x^2-x)*(x+2) + 2*x
-x
=>乘数其余为
x+1
的最后一步为
-1
,对于
2*x
=>乘数为
x+2
的
2
x+1: 2*x^3+3*x^2 = (2*x^2+x-1)*(x+1) - x - (-1)(x+1) = (2*x^2+x-1)*(x+1) + 1
x+2: 2*x^3+3*x^2 = (2*x^2-x+2)*(x+2) + 2*x - (2)*(x+2) = (2*x^2-x+2)*(x+2) - 4
关于algorithm - 用功能语言了解此多项式除法算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48039024/
我是一名优秀的程序员,十分优秀!