haskell 基礎題解(38)

2021-09-26 07:22:55 字數 2686 閱讀 8288

【題目】從控制台輸入若干行。每行若干項,由逗號分開。輸出時,要求把這些內容放到**中,並且要居中對齊。

比如:從鍵盤上輸入了:

a,bb,ccc

aaaa,ccccc

a,b,c,ddd

aa,ccccccccccccccccc,ee

(注意,連續的逗號表示中間的項是空的)

(注意,連續輸入了兩個回車就表示輸入線束了)

這時,程式應該輸出:

顯然,程式需要計算出每個列的寬度。並把每個格仔中的內容安排在合適的位置(通過加入空格)。

通用 haskell 解決這個問題時,要注意把資訊本身,和它的表達形式區分開,這樣各個擊破不僅易於編寫,也易於將來的維護。

上**:

import

data

.list (

delete

)---- 按字元c把串分開為若干詞

split :: char

-> string -

>

[string]

split _ =

split c s = takewhile (

/=c) s : (split c .

delete c . dropwhile (

/=c)

) s----若干行詞 --> 求出每列的最大寬度

getwidths :: [

[string]]-

>

[int

]getwidths =

getwidths (ss:sss)

= f (map length ss)

(getwidths sss)

where

f =f y = y

f x [

]= x

f (x:xs)

(y:ys)

= max x y : f xs ys

----生成在格仔中顯示效果的串列表

gridshow :: [

int]

->

[[string]]-

>

[string]

gridshow l列寬 l多行

|null l多行 =

[f l列寬]

| otherwise = f l列寬 : g l列寬 (head l多行) : gridshow l列寬 (tail l多行)

where

---- f 列寬 ---> 生成邊線

f ="+" f (x:xs)

="+"

++ replicate x '-'

++ f xs

---- g 列寬 內空 ---> 內容行(無內容的列要補空格)

g _ =

"|" g ws [

]= g ws [""]

g (w:ws)

(x:xs)

="|"

++ fill w x +

+ g ws xs

fill w x =

let n =

(w - length x)

`div`2

in replicate n ' '

++ x +

+ replicate (w-n-length x)

' '

ok :: [string]

->

[string]

ok ss = let da = map (split ','

) ss

w = getwidths da

in gridshow w da

----------------------------------------

---- 項間逗號分割,空行則結束輸入

getsomelines :: [string]

-> io [string]

getsomelines xs =

do s <

- getline

ifnull s then

return $ reverse xs

else

getsomelines (s:xs)

main :: io (

)main =

do ss <

- getsomelines [

] putstr $ unlines (ok ss)

程式是由虛線分開的兩個部分。虛線以下是實現 io 互動的部分。它的主要工作是識別使用者連續兩個回車而結束程式,然後把讀入的每個行變成 [string] 列表的一部分,放入到 ss 中,等待乙個純函式去處理它。

split 實現按給定的字元對串進行分割。

getwidths 掃瞄所有的行,得出每個項應該具有的寬度(該列所有元素的寬度的最大值,只是內容,不含格仔)

gridshow 顯示每一行。每一行的顯示,先輸出它的上邊線,再輸出多個項的內容。

當遇到空時,只輸出一行邊線,這就是整個**的下邊線。

內部的函式 g 是輸出內容的。需要注意的是,當內容列表為空,而列寬列表不空時,意味著這行的後面的格仔沒有內容。這相當於內容為空串(因為空格和格仔線還是要畫出來的)。

haskell 基礎題解(06)

題目 如果乙個數的所有真因子 不包含它自身的因子 之和恰等於其自身,則該數為完全數,也稱為完美數 perfect number 完全數有許多奇妙的性質。但它們很稀少,你來求前幾個吧。最小的乙個是 6,因為 6 1 2 3 這個完全數的定義已經很清楚了,如果沒有什麼妙法,就地毯式搜尋也可以。下法就是 ...

haskell 基礎題解(07)

題目 11 1 1 2 1 1 3 3 1 1 4 6 4 1 這個陣勢叫楊輝三角,國外叫帕斯卡三角。前一行的數字中,每兩個相鄰的數字相加就得到下一行的數字。左右兩邊的數永遠是 1 寫個程式,輸出前幾行的楊輝三角。import data.list intersperse yang hui int y...

haskell基礎題解(14)

題目 用自然數蛇形填充乙個 n 階的方陣。當n 5時,形如 這個問題用 haskell 解決時與 題目13 差別甚微。實際上,從函式式的思考習慣看,只要讓有些行作成後反轉一下就可以了。上 ju n f x x 0.n 1 where f row even row take n row n 1.odd...