斐波那契法(即贪心算法)

源程序

在“埃及分数(一)”中,我们讨论了斐波那契法(即贪心算法)。现在使用 Haskell 语言写一个程序来实现该算法吧,下面就是 fib.hs:

1: import System.Environment

2: import Data.Ratio

3:

4: main = do

5: args

6: let x = (\[p, q] -> p % q) $ map read args

7: putStr $ (show x) ++ ": "

8: mapM_ (putStr . (++" ") . show) $ fib x

9: putStrLn ""

10:

11: fib x

12: | p == 1 = [denominator x]

13: | otherwise =

14: let q = (div (denominator x) p) + 1

15: in q : fib (x - (1 % q))

16: where p = numerator x

源程序分析

第 1 行导入 System.Environment 模块,是因为第 5 行的 getArgs 函数属于该模块。

第 2 行导入 Data.Ratio 模块,是因为本程序使用了 Rational 数据类型。

第 5 行的 getArgs 函数用于获取命令行参数。

第 6 行从命令行参数中解析出分数 x 。read 函数将字符串转换为所需的数据类型,这里是 Integer 类型。“%”用于将两个 Integer 类型构造为一个 Rational 类型。小括号中的 lambda 表达式作为一个匿名函数作用在 map read args 上,将 [Integer] 转换为 Rational 。

第 7 行输出分数 x 本身。show 函数将任意类型(这里是 Rational 类型)转换为字符串。

第 8 行调用稍后定义的 fib 函数使用斐波那契法将分数 x 展开为相异单位分数的和。

第 11 至 16 行定义了 fib 函数。这是一个递归函数。该函数的类型是 Rational -> [Integer] 。

第 16 行将分数 x 的分子赋值给 p 。

第 12 行处理分子等于 1 的情况,这时分数 x 已经是单位分数了,直接将分母加到列表中返回就行了。

第 13 至 15 行处理分子大于 1 的情况。

第 14 行将分数 x 的分母除以分子所得的商加 1 后赋值给 q 。

第 15 行用 x - 1/q 作为参数递归调用 fib 函数本身,然后将 q 添加到所得列表的最前面。

编译和运行

直接使用 runhaskell 解释器来运行:

$ runhaskell fib.hs 5 121

5 % 121: 25 757 763309 873960180913 1527612795642093418846225

$ runhaskell fib.hs 118 121

118 % 121: 2 3 8 60 4840

注意,在 Haskell 语言中,有理数(即分数)使用 Rational 数据类型表示,并且使用“%”分隔分子和分母。

当然,也可以使用 ghc 编译器编译后再运行:

$ ghc fib.hs

[1 of 1] Compiling Main ( fib.hs, fib.o )

Linking fib ...

$ ./fib 101 414

101 % 414: 5 23 2070

嗯,运行结果符合我们的预期。

计算单位分数的和

源程序

再写个 Haskell 语言程序来验算结果吧,下面就是 invSum.hs:

1: import System.Environment

2: import Data.Ratio

3:

4: main = do

5: args

6: print $ sum $ map (1%) $ map read args

源程序分析

这个程序主要功能都在第 6 行中实现。

首先,使用 map read args 将 [String] 转换为 [Integer] 。

其次,使用 map (1%) 将 [Integer] 转换为 [Rational],内容是该整数的倒数。“%”是需要两个参数的中缀函数,它将两个 Integer 参数分别作为分子和分母构成一个 Rational 。而“(1%)”是经过柯里化(Currying)后成为只接受一个参数的函数,它把 Integer 参数求倒数得到一个 Rational 。

再次,使用 sum 函数将 [Rational] 列表里的所有元素求和,得到一个 Rational 。

最后,使用 print 函数将 Rational 打印出来。

运行

运行结果:

$ runhaskell invSum.hs 25 757 763309 873960180913 1527612795642093418846225

5 % 121

$ runhaskell invSum.hs 2 3 8 60 4840

118 % 121

$ runhaskell invSum.hs 5 23 2070

101 % 414

一切正常。

与 C 语言程序相比较

在“埃及分数(二)”中,有这两个程序的 C 语言版本。可以看出,Haskell 程序比相应的 C 语言程序要简短。在 C 语言程序中,显式地调用了 GNU MP 高精度算术库进行运算。而在 Haskell 语言程序中,使用了 Integer 和 Rational 数据类型进行运算,隐式地调用了 GNU MP 高精度算术库。

参考资料

埃及分数怎么计算java_埃及分数之斐波那契法相关推荐

  1. 埃及分数怎么计算java_[蓝桥杯][java]埃及分数解法

    import java.util.Scanner; /*  *  标题:埃及分数     古埃及曾经创造出灿烂的人类文明,他们的分数表示却很令人不解.古埃及喜欢把一个分数分解为类似: 1/a + 1/ ...

  2. 小数加分数怎样计算讲解_“分数,小数,百分数 的互化”我这样教学,学生很快就学会了。...

    这部分知识千万不能忽视,用途可大了.我们在进行分数,小数,百分数 四则混合运算时,不会三者之间的转化,很难把题计算准确.那么三者之间怎样转化呢?其实就这么几步: 一,分数化小数,用分数的分子除以分数的 ...

  3. 埃及分数怎么计算java_贪心算法之埃及分数问题(附c++源代码)

    感谢博主提供算法思路http://blog.csdn.net/tterminator/article/details/50927393 博主的是java代码,在这里写个c++代码,只是牛客网中有些很无 ...

  4. JS根据分数,计算名次(分数相同名次相同)

    1.首先先按分数从高到低排序,排序方法参照以下: https://blog.csdn.net/qq_29483485/article/details/85003814 以下是按降序排列好的学生列表: ...

  5. 怎样用计算机算分数题,计算题(分数)

    1.计算: 解析: 将看成是,利用乘法结合律,可得. 2._______. 解析: 该题型是竞赛中送分题型,不过也要仔细认真,不能出任何小差错.根据分析可知: , , ... 提取公因式 ,即可得 原 ...

  6. 埃及分数怎么计算java_JAVA代码—算法基础:埃及分数问题

    埃及分数问题 问题描述 分子为1 的分数称为埃及分数,现输入一个真分数,请将该分数按下面的方法分解为埃及分数: 1.若真分数的分子a能整除分母b,则真分数经过化简就可以得到埃及分数; 2.若真分数的分 ...

  7. 埃及分数问题c语言,埃及分数问题(转)

    今日,小雨和小明来到网络中心,继续与刘老师讨论"数的认识"问题. 刘老师说:"还有一种'埃及分数'需要认识.这是一类分裂分数的思维题,对思维能力的训练很有价值." ...

  8. MODE —— 计算10个分数的平均值(知识点: 数组 变长数组)

    数组是一个数目固定,类型相同的数据项,数组中的数据项称为元素.数组中的元素都是int.long.或者其他类型. 声明一个数组时,要给编译器提供为数组分配内存所需要的所有信息,包括值的类型(决定每个元素 ...

  9. python计算现场得分_浅谈用 Python 计算文本 BLEU 分数

    浅谈用 Python 计算文本 BLEU 分数 BLEU, 全称为 Bilingual Evaluation Understudy(双语评估替换), 是一个比较候选文本翻译与其他一个或多个参考翻译的评 ...

最新文章

  1. 上传图片被防火墙拦截_Web安全:文件上传漏洞
  2. 烂泥:高负载均衡学习haproxy之关键词介绍
  3. Hadoop自学笔记(七)Hadoop环境配置和优化
  4. Windows 全部调试符号包下载
  5. git 撤销修改以及删除文件(亲测最后一个删除后还原)
  6. 数据库:计算地球上两个坐标点之间里程
  7. python计算时间装饰器_python 写一个计算运行时间的装饰器
  8. 【华为云技术分享】华为云多元计算+AI 打造企业级智能数据湖
  9. 单片机ADC采样算法----中位值平均滤波法
  10. php远程文件无法编辑,“脚本编辑器”远程文件编辑漏洞
  11. Spring(二十二):Spring 事务
  12. 黄色量能通达信指标公式!没有未来函数,不加密的副图指标!
  13. 如何改变Android-studio中的APP的名字和图标
  14. 计算机绘图中常用指令,【CAD快捷键运用】CAD常用命令汇总
  15. oracle 启用job,Oracle job启动与关闭
  16. 写完的文档有多少个字?字数统计在word哪里
  17. 12.5-6黄金实时指导、黄金原油操作策略及多空单解套
  18. 乌班图Ubuntu系统安装nacos
  19. Go语言如何实现删除Winmail邮箱系统中收件箱的所有邮件
  20. Java开源JEE框架

热门文章

  1. 多迪技术总监告诉你为什么人工智能用Python?
  2. Python机器学习之编程环境的构建
  3. 计算变量中有多少个bit位是1的方法
  4. JAVA调用JNA修改桌面壁纸
  5. CCPC威海2021M. 810975
  6. 电脑网络连接正常,微信、QQ能正常使用,但无法访问网页
  7. go混淆实现bypassAV(cobaltstrike免杀)
  8. mysql自动递增的id
  9. python开发工具pycharm——创建项目
  10. 【CTF-Reverse】IgniteMe