我正在学习Jason Hickey 的 Objective Caml 简介。
有一个这样的练习:
练习 4.3 假设我们有一个基于以下替换密码的密码系统,其中每个明文都根据下表进行加密。
Plain | A B C D -------------------- Encrypted | C A D B
例如,字符串
BAD
将被加密为ACB
.编写一个函数
check
,给定一个明文字符串s 1和一个密文字符串s 2,true
当且仅当s 2是s 1的密文时返回。如果s 1不是纯文本字符串,您的函数应该引发异常。您可能希望参考第 8 页的字符串操作。随着字母表变大,您的代码如何扩展?[重点补充]
基本上,我为这个练习编写了两个带有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
,然后对于 中的每个 char s1
,我正在寻找s2
相应的 char 并查看它是否是地图中的值。
对此有何建议?