任务是在 n - 数字A中找到(n-1)运算符(+, - ,*)的所有可能组合,以便表达式的重新分配等于数字B.表达式从左到右计算。例如:
We have number A=123 and B=5 : 1*2+3=5
我猜这个任务可能与波兰表示法和解析器的一些用法有关。 所以它像是: 我得到数字123,使它成为字符串“3 2 1”,然后尝试所有可能的运算符组合,如:“3 2 1 + +”“3 2 1 - - ”“3 2 1 * *”“3 2 1 * - “等等,检查它是否等于5.但问题是我真的不明白如何正确找到所有组合。 我也写了一个函数,它使数字中的字符串成为一个计算表达式的函数“3 2 1 * +”。
exprCounting :: String -> Integer
exprCounting = head . foldl stackAnalyzing [] . words
where
stackAnalyzing (x:y:ss) "+" = (x+y):ss
stackAnalyzing (x:y:ss) "-" = (y-x):ss
stackAnalyzing (x:y:ss) "*" = (x*y):ss
stackAnalyzing ss number = read number : ss
toWordString :: Integer -> String
toWordString = addSpace . show
where
addSpace [] = []
addSpace (x:xs) = [x] ++ " " ++ addSpace xs
所以任何人都可以给我关于解决此任务的方法或我应该使用什么工具的建议。
答案 0 :(得分:2)
所以你想要这样的东西
import Control.Monad
data Op = Plus
| Sub
| Mult
deriving(Eq, Show)
denote :: Op -> (Integer -> Integer -> Integer)
denote Plus = (+)
denote Sub = (-)
denote Mult = (*)
combos :: [Integer] -> Integer -> [[Op]]
所以combos [1, 2, 3] 5 == [[Mult, Plus]]
使用它的一个简单方法是列表monad。
eval :: [Integer] -> [Op] -> Integer
eval (n1:n2:ns) (o:os) = eval (denote o n1 n2 : ns) os
eval [n1] [] = n1
eval _ _ = error "eval: Length mismatch"
-- Or, with folds
eval' ns os = case foldl step ns os of
[n] -> n
_ -> error "eval: Length mismatch"
where step (n1 : n2 : ns) o = denote o n1 n2 : ns
combos ns target = filter ( (==target) . eval nums) os
where os = replicateM (length ns -1) [Plus, Sub, Mult]
replicateM
会选择返回由length ns - 1
组成的所有可能长度为Plus, Sub, Mult
的列表的列表。然后我们测试它们以确定它们是否实际上等于正确的值。这不是非常快,但理解起来非常简单。
所以我们分别生成这个运算符列表。现在使用它可以很容易地生成RPN,因为这看起来像家庭作业,我会把那部分留给你:)