這是一個相當典型的make a century
問題。我們有一個自然數列表。在OCaml創造一個世紀
我們有一個可能的運營商列表[Some '+'; Some '*';None]
。
現在我們從上面的可能性中創建一個運算符列表,並將每個運算符插入到數字列表中的每個連續數字之間並計算該值。
(注a None b = a * 10 + b
)
例如,如果運營商列表是[Some '+'; Some '*'; None; Some '+'; Some '+'; Some '+'; Some '+'; Some '+']
,則該值是1 + 2 * 34 + 5 + 6 + 7 + 8 + 9 = 104
。
請找到所有可能的運營商名單,所以the value = 10
。
我能想到的唯一方法就是蠻力。
我生成所有可能的操作員列表。
計算所有可能的值。
然後過濾,所以我得到它產生100
exception Cannot_compute
let rec candidates n ops =
if n = 0 then [[]]
else
List.fold_left (fun acc op -> List.rev_append acc (List.map (fun x -> op::x) (candidates (n-1) ops))) [] ops
let glue l opl =
let rec aggr acc_l acc_opl = function
| hd::[], [] -> (List.rev (hd::acc_l), List.rev acc_opl)
| hd1::hd2::tl, None::optl -> aggr acc_l acc_opl (((hd1*10+hd2)::tl), optl)
| hd::tl, (Some c)::optl -> aggr (hd::acc_l) ((Some c)::acc_opl) (tl, optl)
| _ -> raise Cannot_glue
in
aggr [] [] (l, opl)
let compute l opl =
let new_l, new_opl = glue l opl in
let rec comp = function
| hd::[], [] -> hd
| hd::tl, (Some '+')::optl -> hd + (comp (tl, optl))
| hd1::hd2::tl, (Some '-')::optl -> hd1 + (comp ((-hd2)::tl, optl))
| hd1::hd2::tl, (Some '*')::optl -> comp (((hd1*hd2)::tl), optl)
| hd1::hd2::tl, (Some '/')::optl -> comp (((hd1/hd2)::tl), optl)
| _, _ -> raise Cannot_compute
in
comp (new_l, new_opl)
let make_century l ops =
List.filter (fun x -> fst x = 100) (
List.fold_left (fun acc x -> ((compute l x), x)::acc) [] (candidates ((List.length l)-1) ops))
let rec print_solution l opl =
match l, opl with
| hd::[], [] -> Printf.printf "%d\n" hd
| hd::tl, (Some op)::optl -> Printf.printf "%d %c " hd op; print_solution tl optl
| hd1::hd2::tl, None::optl -> print_solution ((hd1*10+hd2)::tl) optl
| _, _ ->()
所有運營商名單,我相信我的代碼是醜陋的。所以我有以下問題
computer l opl
是使用數字列表和運算符列表進行計算。基本上這是一個典型的數學評估。有沒有更好的實施?- 我已閱讀Pearls of Functional Algorithm Design中的第6章。它使用了一些技術來提高性能。我發現它真的很模糊,很難理解。 任何閱讀它的人都可以幫忙嗎?
編輯
我改進我的代碼。基本上,我將首先掃描運營商列表,粘貼其運營商爲None
的所有號碼。
然後在計算中,如果我遇到一個'-'
,我將簡單地否定第二個數字。
我不明白計算結果的規則。計算不遵循任何明顯的優先級和關聯性規則。例如,'1 - 2 + 3'的計算結果爲-4,但'8/2 * 4'的計算結果爲16. –
作爲第二條評論,您的代碼無法處理諸如'1 + 23'之類的內容 –
@JeffreyScofield您是對的。我的代碼有這樣的問題。 –