字母金字塔
【题目】打印输出如下图的字母金字塔
这题目就不能简单地换“花布”了。
可以看到,每行中的样式不是重复,而是某个序列和它的镜像拼起来的。
下面是 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 行时能不能利用上一行的成果呢?
把上一行从中间分开(有一点重叠),然后中间夹入一个母就可以了。