1

タスクは、(n-1) 個の演算子 (+,-,*)の可能なすべての組み合わせをn個の A から見つけて、式の結果が 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

このタスクを解決する方法や、どのツールを使用する必要があるかについて、誰でもアドバイスをいただけますか。

4

1 に答える 1

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]]

これを使用する簡単な方法はリストモナドです。

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]

replicateMlength ns - 1で構成される長さのすべての可能なリストのリストを返すことを選択しますPlus, Sub, Mult。次に、それらが実際に正しい値に等しいかどうかをテストします。これはそれほど速くはありませんが、理解するのは非常に簡単です。

したがって、この演算子のリストを個別に生成します。そして今、これを使って RPN を生成するのは簡単です。これは宿題のように見えるので、その部分はあなたに任せます :)

于 2013-11-11T15:05:09.787 に答える