zl程序教程

您现在的位置是:首页 >  其它

当前栏目

《Haskell趣学指南》—— 第1章,第1.4节得州区间2

指南 1.4 区间 Haskell 趣学
2023-09-11 14:17:33 时间
本节书摘来自异步社区《Haskell趣学指南》一书中的第1章,第1.4节得州区间2,作者 【斯洛文尼亚】Miran Lipovaca,更多章节内容可以访问云栖社区“异步社区”公众号查看 1.4 得州区间2 该怎样得到一个由1~20所有数组成的列表呢?我们完全可以用手把它们全都录入一遍,但显而易见,这并不是完美人士的方案,完美人士都用区间(range)。

本节书摘来自异步社区《Haskell趣学指南》一书中的第1章,第1.4节得州区间2,作者 【斯洛文尼亚】Miran Lipovaca,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.4 得州区间2
该怎样得到一个由1~20所有数组成的列表呢?我们完全可以用手把它们全都录入一遍,但显而易见,这并不是完美人士的方案,完美人士都用区间(range)。区间是构造列表的方法之一,而其中的值必须是可枚举的,或者说,是可以排序的。

例如,数字可以枚举为1、2、3、4等。字符同样也可以枚举:字母表就是A~Z所有字符的枚举。然而人名就不可以枚举了,“John”后面是谁?我不知道。

要得到包含1~20中所有自然数的列表,只要录入[1..20]即可,这与录入[1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16,17,18,19,20]完全等价。两者的唯一区别是手写一串非常长的列表比较笨。

下面是一些例子:

ghci [1..20] 

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 

ghci [a..z] 

"abcdefghijklmnopqrstuvwxyz"

ghci [K..Z] 

"KLMNOPQRSTUVWXYZ"

区间很聪明,允许你告诉它一个步长。要得到1~20中所有的偶数,或者3的倍数该怎样?只要用逗号将前两个元素隔开,再标上区间的上限就好了:

ghci [2,4..20] 

[2,4,6,8,10,12,14,16,18,20] 

ghci [3,6..20] 

[3,6,9,12,15,18] 

尽管区间很聪明,但它恐怕还是难以满足人们对它过分的期许。比如,你就不能通过[1,2,4,8,16..100]这样的语句来获得100以下的所有2的幂。一方面是因为步长只能标明一次,另一方面就是仅凭前几项,数组后面的项也有可能是无法确定的。

注意:
要得到从20到1之间的列表,[20..1]是不可以的,必须得[20,19..1]。对于没有提供步长的区间(如[20..1]),Haskell会先构造一个空的列表,随后从区间的下限开始,不停地赠长,直到大于等于上限为止。既然20已经大于1了,那么所得的结果只能是个空列表。
你也可以不标明区间的上限,从而得到一个无限长度的列表。在后面我们会讲解关于无限列表的更多细节。取前24个13的倍数该怎样?下面是一种方法:

ghci [13,26..24*13] 

[13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,260,273,286,

299,312] 

但有更好的方法——使用无限长度的列表:

ghci take 24 [13,26..] 

[13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,260,273,286,

299,312] 

由于 Haskell 是惰性的,它不会对无限长度的列表直接求值(不然会没完没了)。它会等着,看你会从它那儿取哪些元素。在这里它见你只要前24个元素,便欣然交差。

下面是几个生成无限列表的函数。
cycle函数接受一个列表作为参数并返回一个无限列表。

ghci take 10 (cycle [1,2,3]) 

[1,2,3,1,2,3,1,2,3,1] 

ghci take 12 (cycle "LOL ")

"LOL LOL LOL "

repeat函数接受一个值作为参数,并返回一个仅包含该值的无限列表。这与用cycle处理单元素列表的效果差不多。

ghci take 10 (repeat 5) 

[5,5,5,5,5,5,5,5,5,5] 

若只是想得到包含相同元素的列表,直接使用replicate函数将更加简单,它取一个参数表示列表的长度,一个参数表示列表中要复制的元素:

ghci replicate 3 10

[10,10,10] 

最后,在区间中使用浮点数要格外小心!浮点数依据定义,只能实现有限的精度。若是在区间中使用浮点数,你就会得到如下的糟糕结果:

ghci [0.1, 0.3 .. 1] 

[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999] 

【算法】4. 寻找两个正序数组的中位数(多语言实现) 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。
数据结构与算法系列一之整数、数组及字符串 系统的学习一下数据结构与算法,主要是通过学习专项突破版的剑指Offer每一部分的典型题目,将每一部分相关的基础内容尽量掌握一下。由于没有太多时间将看过的基础内容都总结整理起来,因此先将题目根据书中的讲解和自己的理解整理一下,后续有时间再系统整理一下每一部分的基础知识,每一行代码都经过本人测试通过。
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。