我目前正在做一个大学作业,我们要在Haskell中实现一个多项式计算器。作业的第一部分是做多边形运算,这已经完成了。如果我们实现一个多项式的解析器,我们会得到额外的学分,我目前正在做的是把一个字符串转换成一个元组[(factor,[(variable,exponent)])]。
这意味着"-10y^4 - 5z^5”=〉“[(-10,[('y ',4)]),(-5,[('z',5)].我遇到的子问题是当我遇到像“5xy^2z^3”这样的多项式时,它们应该存储为[(5,[('x',1),('y',2),('z',3)]]**,我不知道怎么解析它。
有什么建议我可以如何处理这一点?提前感谢您的帮助!
-- Slipts lists by chosen Char, only used with '+' in this project
split :: Char -> String -> [String]
split _ "" = []
split c s = firstWord : (split c rest)
where firstWord = takeWhile (/=c) s
rest = drop (length firstWord + 1) s
-- Remove all spaces from a string, for easier parsing
formatSpace :: String -> String
formatSpace = filter (not . isSpace)
-- Clever way to parse the polynomial, add an extra '+' before every '-'
-- so after we split the string by '+', it helps us keep the '-'
simplify_minus :: String -> String
simplify_minus [] = ""
simplify_minus (x:xs)
| x == '^' = x : head xs : simplify_minus (tail xs)
| x == '-' = "+-" ++ simplify_minus xs
| otherwise = x : simplify_minus xs
-- Splits an String by occurrences of '+' and creates a list of those sub-strings
remove_plus :: String -> [String]
remove_plus s = split '+' s
-- Removes multiplication on substrings
remove_mult :: [String] -> [[String]]
remove_mult [] = []
remove_mult (x:xs) = (remove_power (split '*' x)) : remove_mult xs
-- Function used to separate a variable that has an power. This translates ["y^2] to [["y", "2"]]
remove_power :: [String] -> [String]
remove_power [] = []
remove_power (x:xs) = (split '^' x) ++ remove_power xs
-- Wrapper function for all the functions necessary to the parser
parse_poly :: String -> [(Integer, String, Integer)]
parse_poly [] = []
parse_poly s = map (tuplify) (rem_m (remove_plus (simplify_minus (formatSpace s))))
rem_m :: [String] -> [String]
rem_m l = map (filter (not . (=='*'))) l
helper_int :: String -> Integer
helper_int s
| s == "" = 1
| s == "-" = -1
| otherwise = read s :: Integer
helper_char :: String -> String
helper_char s
| s == [] = " "
| otherwise = s
tuplify :: String -> (Integer, String, Integer)
tuplify l = (helper_int t1, helper_char t3, helper_int (drop 1 t4))
where (t1, t2) = (break (isAlpha) l)
(t3, t4) = (break (=='^') t2)
main :: IO()
main = do
putStr("\nRANDOM TESTING ON THE WAE\n")
putStr("--------------\n")
print(parse_poly "5*xyz^3 - 10*y^4 - 5*z^5 - x^2 - 5 - x")
-- [(5,"xyz",3),(-10,"y",4),(-5,"z",5),(-1,"x",2),(-5," ",1),(-1,"x",1)]
``
1条答案
按热度按时间wqlqzqxt1#
这里已经有了几乎所有的东西,但是你需要递归地使用
break
来获取下一个变量之前的所有东西,你可能还应该使用类似的span
来首先获取系数。