1

我正在尝试将文本格式化为矩形;目前我已经能够让它正确地左对齐,但最后一行没有尽可能地延伸。

我正在尝试计算最佳字段宽度以最小化或完全删除它。

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

顺便说一句,调试 Haskell 代码的最佳方法是什么?(是的,我对此很陌生。)

bestFieldWidth 应该比较行长,直到顶行的长度等于底行的长度,然后返回使此为真的字段宽度。

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

感谢所有回复。谢谢你。

4

3 回答 3

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
于 2011-03-18T18:44:34.140 回答
0

似乎length (last input) == length (head input)一旦为假的条件在随后的调用中永远不会为真area,因此使该函数始终采用分支并无限期地使用andotherwise的相同值继续调用自身。xsinput

造成这种情况的可能原因是您使用了该lines函数,该函数使用换行符拆分字符串,其方式不依赖于lineLength您在函数中的行拆分并且与您的行拆分不一致rect

于 2011-03-16T20:25:31.333 回答
0

作为对您的旁注的回答,这里是调试 Haskell 的绝佳指南:http: //cgi.cse.unsw.edu.au/~dons/blog/2007/11/14

还有 Debug.Trace,它允许您插入打印语句。它当然应该只在调试时使用,因为它会使你的函数产生副作用。

http://hackage.haskell.org/packages/archive/base/latest/doc/html/Debug-Trace.html

于 2011-03-16T21:19:10.917 回答