我在学习 Jason Hickey's Introduction to Objective Caml .
有一个这样的练习:
Exercise 4.3 Suppose we have a crypto-system based on the following substitution cipher, where each plain letter is encrypted according to the following table.
Plain | A B C D -------------------- Encrypted | C A D B
For example, the string
BAD
would be encrypted asACB
.Write a function
check
that, given a plaintext string s1 and a ciphertext string s2, returnstrue
if, and only if, s2 is the ciphertext for s1. Your function should raise an exception if s1 is not a plaintext string. You may wish to refer to the string operations on page 8. How does your code scale as the alphabet gets larger? [emphasis added]
基本上,我用
might-be-stupid-naive
写了两个函数这个练习的方法。我想先征求一下我的解决方案的建议。
然后我想就练习中突出显示的缩放解决方案寻求提示。
使用 if else
let check_cipher_1 s1 s2 =
let len1 = String.length s1 in
let len2 = String.length s2 in
if len1 = len2 then
let rec check pos =
if pos = -1 then
true
else
let sub1 = s1.[pos] in
let sub2 = s2.[pos] in
match sub1 with
| 'A' -> (match sub2 with
|'C' -> check (pos-1)
| _ -> false)
| 'B' -> (match sub2 with
|'A' -> check (pos-1)
| _ -> false)
| 'C' -> (match sub2 with
|'D' -> check (pos-1)
| _ -> false)
| 'D' -> (match sub2 with
|'B' -> check (pos-1)
| _ -> false)
| _ -> false;
in
check (len1-1)
else
false
到处使用纯匹配let check_cipher_2 s1 s2 =
let len1 = String.length s1 in
let len2 = String.length s2 in
match () with
| () when len1 = len2 ->
let rec check pos =
match pos with
| -1 -> true
| _ ->
let sub1 = s1.[pos] in
let sub2 = s2.[pos] in
(*http://stackoverflow.com/questions/257605/ocaml-match-expression-inside-another-one*)
match sub1 with
| 'A' -> (match sub2 with
|'C' -> check (pos-1)
| _ -> false)
| 'B' -> (match sub2 with
|'A' -> check (pos-1)
| _ -> false)
| 'C' -> (match sub2 with
|'D' -> check (pos-1)
| _ -> false)
| 'D' -> (match sub2 with
|'B' -> check (pos-1)
| _ -> false)
| _ -> false
in
check (len1-1)
| () -> false
好的。以上两种解决方案类似。我制作了这两个,因为在这里http://www.quora.com/OCaml/What-is-the-syntax-for-nested-IF-statements-in-OCaml ,有人说
if else
不是首选。这基本上是我第一次写
not-that-simple
在我的一生中发挥作用。所以我真的很想得到建议 这里。例如,
match
在 if else
? rec
或 use the rec
正确吗? in check (len1-1)
正确的? 缩放它
练习问
How does your code scale as the alphabet gets larger?
.我现在真的没有线索。在 Java 中,我会说我会有一个 map
,然后对于 s1
中的每个字符, 我在找 s2
对于相应的字符并查看它是否是 map 中的值。对此有何建议?
最佳答案
这是一个简单的解决方案:
让 tr = 函数
| 'A' -> 'C'
| 'B' -> 'A'
| 'C' -> 'D'
| 'D' -> 'B'
| _ -> 失败“不是明文”
让检查 ~tr s1 s2 = (String.map tr s1) = s2
检查 ~tr "坏""ACD"
您可以通过使用 tr 组合来添加更多字母。 IE。
让 comp c1 c2 x = try (c1 x) with _ -> (c2 x)
让 tr2 = comp tr(函数 | 'X' -> 'Y')
关于functional-programming - 如何在 Ocaml 中编写模式匹配以便易于扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14343379/