我是Ocaml的新手,我对此代码有疑问(如下)。我正在尝试编写一个程序来排序数组。我将数组分成两半,然后我在这两个数组上使用了Array.sort(我稍后会修复它,所以我不会使用Array.sort)。然后我想比较这两个数组中的元素,但我的代码不起作用。 谁能告诉我问题出在哪里?
let a =[|5;4;2;6;1;3|] ;;
let n = Array.length a;;
let l= Array.sub a 0 (n/2);;
Array.sort compare l;;
l;;
let ll= Array.length l;;
let r= Array.sub a (n/2) (n/2);;
Array.sort compare r;;
r;;
let lr=Array.length r;;
let merge l r a =
let k =ref 0 in
let i = ref 0 in
let j =ref 0 in
while( !i<ll && !j< lr) do
if(l.(!i) <= r.(!j)) then
a.(!k) <- l.(!i)
i:= !i+1
else begin
a.(!k) <- r.(!j)
j:= !j+1;
k:= !k+1
end;
while (!i<ll) do
a.(!k)<-l.(!i)
i:= !i+1;
k:=!k+1;
done;
while (!j<ll) do
a.(!k) <-r.(!j)
j:= !j+1;
k:= !k+1
done;
done;;
merge l r a;;
答案 0 :(得分:1)
我太新了评论,但会指出每个块都需要括号()
或begin ... end
。因此,您的第一个if
语句应该在行尾有then begin
。 begin
和else
之间的陈述需要使用分号来区分它们,如下所示:
if(l.(!i) <= r.(!j)) then begin
a.(!k) <- l.(!i);
i:= !i+1
end else begin
a.(!k) <- r.(!j);
j := !j+1;
k:= !k+1
end;
while循环的前两行也需要分号,因为它们也是一个语句块。请注意,块中的最后一个语句不需要使用分号。它们是分隔符,而不是结束语。此外,作为快捷方式,您可以将incr i
用于i := !i + 1
和类似语句。此外,永远不要使用l或ll作为变量名。 : - )
答案 1 :(得分:1)
您的问题来自您对指令的误解。让我们尝试以简单明了的方式解释它:
bool
,int
,function
...)unit
,因为实际上,这是什么它确实)。如果你有一个序列(这是调用多个指令一个接一个地执行的方式),你可以用;
将它们分开。
所以,例如,如果我写这个
let f x = x := 1; print_int !x; print_newline ()
我有一个序列,我必须将我的指示与;
分开。
如果我写道:
let f x = x := 1 print_int !x print_newline ()
您可以轻松了解OCaml无法知道指令的分隔位置(是x := 1 print_int; !x
还是其他?)这就是您需要;
的原因。
问题出现在if
。
如果你写
if cond then instr1; instr2
解析的是
(if cond then instr1); instr2
是的,if cond then instr1
是一条指令,因为它返回unit
,不是吗?因此,instr2
块中不存在then
。
但如果你写
if cond then let e1 = e2 in instr1; instr2
然后instr2
位于then
块中,因为构造let ... in
创建了一个块,所有指令都嵌套在该块中。
如果您从OCaml开始,我的宝贵建议是: 始终在您的条件中写begin ... end
。你可以放心,你所写的就是你认为被解析的东西。