2011-03-16 101 views
1

我试图将文本格式化为矩形的形状;目前我已经能够正确地得到它,但最后一行并没有尽可能延长。Haskell:递归问题

我试图计算最佳的字段宽度,以最大限度地减少或完全删除它。

我完全卡住了。下面的代码显示了相关的功能。目前它陷入了无限循环。 我哪里错了?

在附注中,调试Haskell代码的最佳方法是什么? (是的,我对此很新颖。)

optimalFieldWidth应该比较行长度,直到顶行的长度等于底行的长度,然后返回导致它的字段宽度真正。

module Main where 

import System 
import Data.List 

main = do 
    (f:_) <- getArgs 
    xs <- getContents 
    putStr (show (bestFieldWidth maxLineLength xs)) 

bestFieldWidth :: Int -> String -> Int 
bestFiledWidth _ [] = 0 
bestFieldWidth lineLength xs 
    | length (last input) == length (head input) = lineLength 
    | otherwise = bestFieldWidth (length (head (rect (lineLength-1) xs))) xs 
    where input = lines xs 

rect :: Int -> String -> [String] 
rect _ [] = [] 
rect lineLength xs 
    | length input <= len = [input] 
    | otherwise   = take len input : rect len (drop len input) 
    where input = trim xs 
     len = bestFieldWidth lineLength xs 

maxLineLength :: Int 
maxLineLength = 40 

所有回复赞赏。谢谢。

回答

1

我想我应该把实际的解决方案在这里情况下,任何其他疯子想做到这一点。 请注意,它是由白痴写的,所以它可能不是最优雅的解决方案。

maxFieldWidth :: Int 
maxFieldWidth = 30 

rect :: String -> String 
rect xs = (unlines (chunk (bestFieldWidth (maxFieldWidth) (lines input)) input)) 
    where input = itemsReplace '\n' ' ' xs 

--Should be called with the point maximum desired width as n 
bestFieldWidth :: Int -> [String] -> Int 
bestFieldWidth _ [] = error "bestFieldWidth: Empty List" 
bestFieldWidth n xs 
    | n == 6 = 6 
    | 1 == (length (last input)) = n 
    | otherwise = (bestFieldWidth (n-1) xs) 
    where input = chunk n (unlines xs) 

chunk :: Int -> [a] -> [[a]] 
chunk n [] = [] 
chunk n xs = ys : chunk n zs 
    where (ys,zs) = splitAt n xs 

itemsReplace :: Eq a => a -> a -> [a] -> [a] 
itemsReplace _ _ [] = [] 
itemsReplace c r (x:xs) 
    | c == x = r:itemsReplace c r xs 
    | otherwise = x:itemsReplace c r xs 
0

看来,条件length (last input) == length (head input)一次假从未在后续调用area为真,从而使这一功能始终以otherwise分支,并保持自称无限期使用的xs相同的值,从而input

的这个可能的原因是您使用lines功能,其将使用新行字符的字符串,在不依赖于lineLength,不符合在rect功能的分线的方式。

+0

对不起。我刚刚意识到这个名字是多么的错误。它应该比较行长度,直到顶行的长度等于底行的长度,然后返回导致其为真的字段宽度。 – ratbum 2011-03-16 20:27:19

+0

@ratbum我已更新我的答案,以解释您添加的信息。 – Rotsor 2011-03-16 20:51:53