2017-09-28 66 views
1

我已經編寫了一個程序,它將一條消息作爲一個字符串並通過用X填充消息來返回一個字符串,這樣字符串長度恰好具有4個因子,然後基本上重新排列消息,就好像它已經被組織在一個網格中,而不是橫過去。例如,輸入「Haskell」將返回字符串「HealslkX」。我編寫了一個編碼這個字母的程序,但是在編寫一個程序時遇到了麻煩,該程序可能會顛倒之前的程序並解碼字母,尤其是使用removeX函數應該刪除X填充。以下是我有:編寫代碼來反向Haskell程序

編碼:

import Data.List 

factors :: Int -> [Int] 
factors n = [x | x <- [1..n], n `mod` x == 0] 

split :: Int -> [a] -> [[a]] 
split _ [] = [] 
split n xs = 
    let (ys, zs) = splitAt n xs 
    in ys : split n zs 

encode :: [Char] -> [Char] 
encode (x:xs) = if (length (factors (length xs))) == 4 then concat 
(transpose (split ((factors (length xs))!!2) xs)) 
else encode (xs ++ ['X']) 

解碼:

import Data.List 

factors :: Int -> [Int] 
factors n = [x | x <- [1..n], n `mod` x == 0] 

split :: Int -> [a] -> [[a]] 
split _ [] = [] 
split n xs = 
    let (ys, zs) = splitAt n xs 
    in ys : split n zs 

removeX :: [a] -> [a] 
removeX xs = if (last xs) == 'X' then ((init xs) && removeX xs) 
else xs 

decode :: [Char] -> [Char] 
decode (x:xs) = removeX (concat (transpose (split ((factors (length xs))!!1) xs))) 

回答

3

只需使用removeX (init xs),而不是init xs && removeX xs。 Haskell不是程序性的(你不會寫下一系列的變化),而是功能性的(你寫下可以產生新舊結果的函數)。儘管如此,還沒有閱讀剩餘的代碼來查看是否有其他錯誤。

還考慮removeX = reverse . dropWhile ('X'==) . reverse以獲得更好的效率。列表是單鏈接的,所以最後的訪問和修改相對昂貴。

+0

'dropWhileEnd'現在在Data.List中。 –