用Haskell创建一个空心矩形

时间:2016-01-25 02:59:52

标签: string haskell recursion

我试图找出一种方法,我可以使用haskell创建一个带有孔的矩形,如图所示

Main > putStr (hollowedrectangle 4 5)

 *****
 *   *
 *   *
 *****

但是,我知道下面的代码首先实现了topnbot行,因此它当前在中间返回一个完整的星号行(topnbot)。我试图找出我需要在代码中更改的内容,因此它给出了上面的结果,而不是下面的结果。

topnbot :: Int->String
topnbot x 
   | x <= 0 = ""
   | x == 1 = "*"++topnbot(x-1)
   | x > 0 = "*"++topnbot(x-1)

leftnright :: Int->Int->String
leftnright x y
   | y==1 = "*"
   | x < 0 = ""
   | x >= 0 = "*"++mid (y-1)
   where
    mid :: Int->String
    mid z
      | z <= 0 = ""
      | z == 1 = leftnright x z
      | z > 0 =  " "++mid (z-1)

hollowedrectangle :: Int->Int->String
hollowedrectangle a m 
  | m == 0 = topnbot m
  | a == 0 = ""
  | a < 3 = topnbot m
  | a >= 3 && m >= 3 = topnbot m ++"\n"++leftnright a m ++ "\n" ++hollowedrectangle (a-1) m 

这导致

  Main > putStr (hollowedrectangle 4 5)
    *****
    *   *
    *****
    *   *
    *****

谢谢!

1 个答案:

答案 0 :(得分:4)

你的代码比我喜欢读的更长更复杂,所以让我给你一些提示:

首先,写一个函数

replicate :: Int -> a -> [a]

表示给定长度的列表,其元素都是给定的长度。所以

replicate 3 7 = [7,7,7]
replicate 4 'a' = "aaaa"

为提高效率,请在不使用replicate的情况下撰写++。通过键入

来测试它的效率
replicate (2^30) 'x' !! 10000

在GHCi提示符下。如果你在吐出答案之前有时间眨眼,你就做错了。

您能弄清楚如何使用replicate++来生成顶行,底行和其中一行?你能弄清楚如何使用replicate生成所有中间行吗?

P.S。,replicate函数在标准库中可用,但在编写之前不应该查找它。