【发布时间】:2014-03-09 17:41:10
【问题描述】:
我是 haskell 的新手,我有一个任务,涉及将字符串解析成树并用它做一些垃圾。 我刚刚完成(现在一切功能都很好),但随着我的开发,我一直在使用静态字符串定义,而不是每次都输入输入。
这是一个示例输入。 ex1 = "C1,8R1+4;R3-4C2C7+4;R5R2-3C1-6+3;R2-3C6+2;"
我需要做的最后一件事是处理用户输入(输入应该来自标准输入,而不是某些定义)。 我不仅不知道如何获得输入,而且我开始认为由于 haskell 的性质,我被彻底搞砸了。我的意思是,整个语言似乎只是嵌套语句中的嵌套语句,带有递归嵌套语句等等。这对我来说是一个令人困惑的混乱。我什至不知道该问什么……到目前为止,我尝试获取用户输入意味着我需要开始将输入作为参数传递给整个程序中的每个函数,以使其编译。 有什么方法可以将用户输入转换为上述定义?或者甚至只是用全局字符串变量作弊?我很绝望:(谢谢。
我知道发布我的整个程序可能很糟糕,但我觉得我需要这样做,这样我才能展示这一切是如何交织在一起的,因此很难弄清楚如何进行。
实际使用ex1定义的是函数createNodeContentList(靠近底部)。
import Text.Regex.Posix
import Data.List.Split
ex1 = "C1,8R1+4;R3-4C2C7+4;R5R2-3C1-6+3;R2-3C6+2;"
treePat = "(([RC][0-9]*[,-]?[0-9]*)*[+][0-9]*;)"
rangePat = "([RC][0-9]*[-][0-9]*)"
nodePat = "([RC][0-9,-]*)"
breakIntoInputTrees x = endBy ";" x
breakIntoInputNodes x = getAllTextMatches $ x =~ nodePat :: [String]
data NodeContent = NodeContent { idy::Char, vals::[Int] } deriving (Show)
data Tree = Node { content::NodeContent, children::[Tree]} deriving (Show)
data GridMod = GridMod { rows::[Int], cols::[Int], mod::[Int] } deriving (Show)
data Path = Path { pathSum::Int, corner::[Char] } deriving (Show, Eq, Ord)
go = printCornerNames $ maxOfMinPaths (maxOfMinValues 0 listOfMinPaths) listOfMinPaths
printCornerNames pathList = putStrLn $ unwords [ corner path | path <- pathList ]
maxOfMinPaths max [] = []
maxOfMinPaths max (h:t) = if (pathSum h == max)
then h:maxOfMinPaths max t
else maxOfMinPaths max t
maxOfMinValues max [] = max
maxOfMinValues max (h:t) = if (pathSum h > max)
then maxOfMinValues (pathSum h) t
else maxOfMinValues max t
listOfMinPaths = findMinimums finalArray
findMinimums array = [quadMinPath array center 0 rMod cMod | rMod <- [-1,1], cMod <- [-1,1]]
quadMinPath array (r,c) sum rMod cMod
| isCorner (r,c) = Path (sum + (posVal array r c)) (cornerName (r,c))
| otherwise = decidePaths array (r,c) sum rMod cMod
decidePaths array (r,c) sum rMod cMod
| (validRow (r + rMod) && validCol (c + cMod)) =
minimum [
quadMinPath array (r + rMod, c) (sum + (posVal array r c)) rMod cMod,
quadMinPath array (r, c + cMod) (sum + (posVal array r c)) rMod cMod
]
| (validRow (r + rMod)) = quadMinPath array (r + rMod, c) (sum + (posVal array r c)) rMod cMod
| otherwise = quadMinPath array (r, c + cMod) (sum + (posVal array r c)) rMod cMod
posVal array r c = array !! (toIndex r c)
isCorner x = elem x [(1,1), (1,cMax), (rMax,1), (rMax,cMax)]
cornerName x | x == (1,1) = "TOP-LEFT" | x == (1,cMax) = "TOP-RIGHT"
| x == (rMax,1) = "BOTTOM-LEFT" | x == (rMax,cMax) = "BOTTOM-RIGHT"
validRow r = if (r >= 1 && r <= rMax) then True else False
validCol c = if (c >= 1 && c <= cMax) then True else False
rMax = fst findMaximums
cMax = snd findMaximums
center = (quot (fst findMaximums) 2 + 1, quot (snd findMaximums) 2 + 1)
finalArray = modifyArray (createArray findMaximums) (toModifiers createGridModders)
modifyArray array [] = array
modifyArray array ((r,c,m):t) = modifyArray (addToArray array (toIndex r c) m) t
addToArray array index mod = (take index array) ++ [(mod + array !! index)] ++ (drop (index + 1) array)
toIndex r c = (r - 1) * (snd findMaximums) + c - 1
createArray (maxR,maxC) = (take (maxR * maxC)) (repeat 0)
printArray array = mapM_ putStrLn [ printRow row | row <- (chunksOf (snd findMaximums) array)]
printRow row = unwords (map show row)
toModifiers gridModders = flat [ toModifier gw | gw <- gridModders ]
toModifier (GridMod r c m) = [ (x,y,head m) | x <- r, y <- c]
createGridModders = adjustForMaximums (treeWalk (GridMod [] [] []) buildAllTrees)
adjustForMaximums gridMods = [ fillMax gm findMaximums | gm <- gridMods ]
fillMax (GridMod [] [] m) (maxR,maxC) = (GridMod [1..maxR] [1..maxC] m)
fillMax (GridMod [] c m) (maxR,maxC) = (GridMod [1..maxR] c m)
fillMax (GridMod r [] m) (maxR,maxC) = (GridMod r [1..maxC] m)
fillMax (GridMod r c m) (maxR,maxC) = (GridMod r c m)
treeWalk (GridMod r c m) (Node (NodeContent 'R' v) []) = [(GridMod v c m)]
treeWalk (GridMod r c m) (Node (NodeContent 'C' v) []) = [(GridMod r v m)]
treeWalk (GridMod r c m) (Node (NodeContent 'M' v) []) = [(GridMod r c v)]
treeWalk (GridMod r c m) (Node (NodeContent 'R' v) ch) = flat [ (treeWalk (GridMod v c m) tree) | tree <- ch ]
treeWalk (GridMod r c m) (Node (NodeContent 'C' v) ch) = flat [ (treeWalk (GridMod r v m) tree) | tree <- ch ]
treeWalk (GridMod r c m) (Node (NodeContent 'M' v) ch) = flat [ (treeWalk (GridMod r c v) tree) | tree <- ch ]
treeWalk (GridMod r c m) (Node (NodeContent 'Z' v) ch) = flat [ (treeWalk (GridMod r c m) tree) | tree <- ch ]
flat [] = []
flat (h:t) = h ++ flat t
findMaximums = (oddify(findMaxRows buildAllTrees), oddify(findMaxCols buildAllTrees))
oddify num = num + ((Prelude.mod num 2) - 1) * (-1)
findMaxRows (Node (NodeContent 'R' v) []) = maximum v
findMaxRows (Node (NodeContent _ _) []) = 0
findMaxRows (Node (NodeContent 'R' v) c) = maximum (v ++ [ findMaxRows x | x <- c ])
findMaxRows (Node (NodeContent _ _) c) = maximum [ findMaxRows x | x <- c ]
findMaxCols (Node (NodeContent 'C' v) []) = maximum v
findMaxCols (Node (NodeContent _ _) []) = 0
findMaxCols (Node (NodeContent 'C' v) c) = maximum (v ++ [ findMaxCols x | x <- c ])
findMaxCols (Node (NodeContent _ _) c) = maximum [ findMaxCols x | x <- c ]
buildAllTrees = Node (NodeContent 'Z' []) (buildIntoTrees (createNodeContentList))
buildIntoTrees x = [ buildIntoTree treeNodeContentList | treeNodeContentList <- x ]
buildIntoTree (h:t) = Node h [ buildSubTree subList | subList <- (easyList t) ]
buildSubTree (h:t) = Node h [ Node content [] | content <- t ]
easyList nodeContentList = tail (simplifyNodeList (idy (head nodeContentList)) nodeContentList [] [])
simplifyNodeList identity [] fullList nextList = fullList ++ [nextList]
simplifyNodeList identity (h:t) fullList nextList = if (idy h == identity)
then simplifyNodeList identity t (fullList ++ [nextList]) [h]
else simplifyNodeList identity t fullList (nextList ++ [h])
createNodeContentList = [ tupleTreeToNodeContentList tupleTree | tupleTree <- (parseToListOfTupleTrees ex1)]
parseToListOfTupleTrees input = [ toTupleTree x | x <- breakIntoInputTrees input]
toTupleTree x = ('M', [modifier x]):[ createTupleNode y | y <- breakIntoInputNodes x]
modifier x = read (last (splitOn "+" x )) :: Int
createTupleNode nodeStr = (head nodeStr, getNodeNumbers nodeStr)
getNodeNumbers nodeStr = if (nodeStr =~ rangePat :: Bool)
then extractRange (onlyNumbers nodeStr)
else onlyNumbers nodeStr
onlyNumbers str = toInt (words (replaceNonDigit str))
extractRange numList = [head numList .. last numList]
replaceNonDigit [] = []
replaceNonDigit ('R':t) = ' ':replaceNonDigit t
replaceNonDigit ('C':t) = ' ':replaceNonDigit t
replaceNonDigit ('-':t) = ' ':replaceNonDigit t
replaceNonDigit (',':t) = ' ':replaceNonDigit t
replaceNonDigit (h:t) = h:replaceNonDigit t
toInt :: [String] -> [Int]
toInt = map read
tupleTreeToNodeContentList x = [ tupleNodeToNodeContent tupleNode | tupleNode <- x ]
tupleNodeToNodeContent x = NodeContent (fst x) (snd x)
【问题讨论】:
-
首先,您应该使用一些(可能是简化的)代码来展示您的问题。
-
您是在告诉我们您一次性解析了该字符串吗?当然,您有一些顶级功能,您可以在其中使用
ex1并将其或其中的一部分传递给其他功能?给我们看看这个吧。