我有一个函数can_obtain
来证明字符串init
是否可以使用以下条件转换为字符串target
:
init
和target
只包含字母“X”和/或“Y”(如“XY”,“XXX”,“YYXY”,“Y”等)< / LI>
target
超过init
target
的选项是
init
或init
这是一个功能,删除了contains
和reverse
之类的简单操作。
let can_obtain init target =
let final =
let rec reduce i text =
if i >= String.length target then text
else
let next =
let branchX = text ^ "X" in
let branchY = (reverse text) ^ "Y" in
if contains target branchX then branchX
else if contains target branchY then branchY
else text
in
reduce (i+1) next
in
reduce (String.length init) init
in
final = target
;;
问题在于这些转换返回true
,这是正确的
(* concat "X" only *)
(* "XY" -> "XYX" -> "XYXX" *)
can_obtain "XY" "XYXX";;
(* reverse and concat "Y" only *)
(* "XY" -> "YXY" -> "YXYY" -> "YXYYY" *)
can_obtain "XY" "YXYYY";;
(* reverse and concat "Y", then concat "X" lastly *)
(* "XY" -> "YXY" -> "YXYY" -> "YYXYY" -> "YYXYYX" *)
can_obtain "XY" "YYXYYX";;
但是,如果在过渡“X”的某个时刻连接,该函数将拒绝切换到反向分支并返回false
:
(* concat "X", then tries to reverse then concat "Y" *)
(* "XY" -> "XYX" -> "XYXY" *)
can_obtain "XY" "XYXY";; (* false *)
我知道我在这里只缺少一小块,代码看起来也非常混乱。我真的很感激一些帮助。
答案 0 :(得分:2)
can_obtain
是一个递归函数 - 所以让我们先定义停止条件:
停止条件:
如果不符合停止条件,那么我们必须进一步尝试使用2假设:(init ^ "X")
,((reverse init) ^ "Y")
所以代码导致:
let rec can_obtain init target =
if init = target then
true
else if String.length init >= String.length target then
false
else
(can_obtain (init ^ "X") target) || (can_obtain ((reverse init) ^ "Y") target)
答案 1 :(得分:1)
只是查看代码,显而易见的问题是N可能包含branchX和branchY。在那种情况下(在我看来)你想要追求两种可能性,但你只追求第一种。
<强>更新强>
另一个观察是,如果N包含分支或其反转,您可能想要追求分支。您的其中一个操作会反转字符串,对于您所知道的,此操作可能会应用奇数次。