【问题标题】:Printing Pascal's triangle in Haskell在 Haskell 中打印 Pascal 的三角形
【发布时间】:2016-04-27 16:46:10
【问题描述】:

我刚开始学习 Haskell,一直在网上做一些题。大多数时候,我可以找出解决方案,但我无法以预期的输出格式打印出来。

例如,我尝试做一个帕斯卡三角程序。我发现了如何将 Pascal 的三角形生成为 Ints 列表的列表,但我不知道如何打印它。

这是我的代码。

import Data.List
pascal n = map liner [0..n]
    where liner x = map (comb x) [0..x]

comb n 0 = 1
comb 0 r = 0
comb n r = comb (n-1) (r-1) * n `div` r 

main = do
    order <- getLine
    let output = pascal . (read :: String -> Int) $ order
    print output 

目前的输出是这样的

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

我想打印成表格

1
1 1
1 2 1
1 3 3 1
...

我该怎么做?我尝试过使用诸如 mapM_ 或插入“”之类的东西,但没有运气。我还没有进入 monad,所以我不明白 mapM 是如何工作的。

【问题讨论】:

  • 真的不需要理解 monads。 f = unlines . map (intercalate " " . map show) 将从 [[Int]] 值中生成所需的 String 值;只需将结果传递给putStr
  • intercalate " " 只是unwords - 你可以通过putStr . unlines . map (unwords . map show) 得到它
  • 啊漂亮。我混合了linesunlinesmap 都错了。我没有以正确的方式使用show。谢谢!
  • @Carsten 啊,是的;我把它复杂化了。

标签: haskell pascals-triangle


【解决方案1】:

有几种不同的方法可以做到这一点,但最直接的 (IMO) 方法如下。

putStrLn $ intercalate "\n" $ map (intercalate " " . map show) output

这首先将列表中的所有数字转换为字符串(使用show)。然后它将最里面的列表转换为字符串,其中每个元素用空格分隔(使用intercalate " ")。然后它将 outermost 列表转换为一个字符串,其中每个元素由 newline 分隔(使用intercalate "\n")。最后,它将生成的字符串推送到标准输出。用这个替换你的main 的最后一行,它应该做你想做的事。

编辑: 正如 Yakym 在他的回答中提到的那样,intercalate " "intercalate "\n" 可以替换为 unwordsunlines,使上面的代码更加简洁(它也消除了导入 Data.List 的需要)。

putStr $ unlines $ map (unwords . map show) output

我将putStrLn 更改为putStr,因为unlines 会自动在输出末尾添加换行符。

【讨论】:

    【解决方案2】:

    还有像 unlinesunwords 这样的函数可以在字符串列表上进行自然插入。

    pascal :: [[Int]]
    pascal = iterate (\row -> zipWith (+) ([0] ++ row) (row ++ [0])) [1]
    
    printPascal :: [[Int]] -> IO ()
    printPascal = mapM_ (putStrLn . unwords . map show)
    
    --*Main> printPascal $ take 10 pascal 
    --1
    --1 1
    --1 2 1
    --1 3 3 1
    --1 4 6 4 1
    --1 5 10 10 5 1
    --1 6 15 20 15 6 1
    --1 7 21 35 35 21 7 1
    --1 8 28 56 70 56 28 8 1
    --1 9 36 84 126 126 84 36 9 1
    

    【讨论】:

    • [0] ++ row 可以简化为0 : row
    • 你是对的;我从 Haskell wiki wiki.haskell.org/Blow_your_mind 借用了这条线 - 我想上面的版本是由于对称性。
    猜你喜欢
    • 2021-11-29
    • 1970-01-01
    • 2013-10-20
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2020-10-06
    相关资源
    最近更新 更多