1

テキストを長方形の形にフォーマットしようとしています。現在、適切に左揃えにすることができましたが、最後の行は可能な限り延長されていません。

これを最小化または完全に削除するために、最適なフィールド幅を計算しようとしています。

私は完全に立ち往生しています。以下のコードは、関連する機能を示しています。現時点では、無限ループに陥っています。どこが間違っているのですか?

ちなみに、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

すべての回答をいただければ幸いです。ありがとうございました。

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)一度falseになるという条件は、以降のへの呼び出しでは決して真にならないようですarea。したがって、この関数を常にotherwise分岐させ、同じ値でxs、したがって、を無期限に呼び出し続けますinput

これの考えられる原因は、関数内の行分割に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 に答える