【发布时间】:2017-10-20 17:34:11
【问题描述】:
我想找出满足 的第一个n。如果我使用另一种语言,例如 c/c++,这是一件简单而容易的事情,但我不知道如何在 Haskell 中实现它。
#include <iostream>
long double term(int k) { return 1.0/(k*k+2.0*k); }
int main() {
long double total = 0.0;
for (int k=1;;k++) {
total += term(k);
if (total>=2.99/4.0) {
std::cout << k << std::endl;
break;
}
}
return 0;
}
我将 dropWhile 与有序列表一起使用,并取 1 来提取第一个。
term k = 1.0/(k*k+2.0*k)
termSum n = sum $ take n $ map term [1..]
main = do
let [(n,val)] = take 1 $ dropWhile (\(a,b)->b <= 2.99/4.0) $ map (\n->(n,termSum n)) [1..]
print n
我知道这很可怕。写这个的最好和直观的方法是什么?
回复: 感谢您的精彩回答!使用修复功能的那个似乎是我机器中最快的(Redhat 6.4 64bit / 80GB 内存)
method#0 take 1 and dropWhile(我的初始实现)
threshold=0.74999 n=99999 time=52.167 sec
方法#1 使用修复功能
threshold=0.74999 n=99999 time=0.005 sec
threshold=0.74999999 n=101554197 time=1.077 sec
threshold=0.7499999936263 n=134217004 time=1.407 sec
方法#2 倒退
threshold=0.74999 n=99999 time=0.026 sec
threshold=0.74999999 n=101554197 time=21.523 sec
threshold=0.7499999936263 n=134217004 time=25.247 sec
method#3 命令式方式
threshold=0.74999 n=99999 time=0.008 sec
threshold=0.74999999 n=101554197 time=2.460 sec
threshold=0.7499999936263 n=134217004 time=3.254 sec
重来: 我注意到无论我使用什么实现方式(修复、命令式或递归方式),如果阈值大于 0.7499999936264 ......它永远不会结束......为了让 f(n) 大于 0.7499999936264,我认为我们只是由于 ![f(n)=\frac_{3n^2+5n}^{4n^2+12n+8}] 需要计算高达 150,000,000 的项。我使用 Integer 而不是 Int,但它也没有帮助。如果我将阈值设置为大于 0.7499999936264 ...,是否有任何原因无法完成?
【问题讨论】:
-
我可能会用显式递归来编写它。我认为这里看起来很干净。
标签: haskell