haskell 基础题解(12)

字母金字塔

【题目】打印输出如下图的字母金字塔
在这里插入图片描述
这题目就不能简单地换“花布”了。
可以看到,每行中的样式不是重复,而是某个序列和它的镜像拼起来的。

下面是 haskell 的解法:

import Data.List (intersperse)

zi_mu = ['A'..]
ta    = [ take i zi_mu ++ reverse(take (i-1) zi_mu) | i<- [1..] ] 
kong  = [ replicate i ' ' | i<-[0..] ]

ok n = zipWith (++) (reverse $ take n kong) (take n ta) 

out xs = concat $ intersperse "\n" xs
main = putStrLn $ out (ok 9)

其它题解中提到,haskell 的一个倾向:不自觉地向通用的方向考虑。
目前的无限序列是 ABCDEFG… (其实这种字母的无法无限的)
如果你要换成 12345… 程序只要修改一个字符即可。

如果你不习惯于用无限序列,也可以用递归法直接构造。
代码:

import Data.List (intersperse)
import Data.Char (ord, chr)

ta :: Int -> [String]
ta 0  = []
ta n  = ta (n-1) ++ [f n] where
  f :: Int -> String
  f 1 = "A"
  f n = let s = f (n-1)
        in take (n-1) s ++ [chr(ord 'A' + n - 1)] ++ drop (n-2) s  

kong  = [ replicate i ' ' | i<-[0..] ]
ok n = zipWith (++) (reverse $ take n kong) (ta n) 

out xs = concat $ intersperse "\n" xs
main = putStrLn $ out (ok 9)

ta 由原来的无限列表,改为吃入一个整数来决定多大规模。
构造一个 n 层的塔,就是先去构建 n-1 层的塔后,再加入一行就可以了。
如何构造一行呢? 假如建好了第 n 行,再建 n+1 行时能不能利用上一行的成果呢?
把上一行从中间分开(有一点重叠),然后中间夹入一个母就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值