1

我有一个 R3 空间,我正在尝试用 OCAML 函数解决一些数学“问题”。

定义函数“move”,它根据plane_name(例如plane1)和向量(x,y,z)移动平面:

例子:

plane1 = [(1,2,-3); (10,5,2); (-2,3,7)]
move plane1 (1,2,-3);;
- : (int * int * int) list = [(2, 4, -6); (11, 7, -1); (-1, 5, 4)]

谢谢

4

1 回答 1

4

我将限制我对问题 3 的回答。

我不知道您对 OCaml 的了解以及对您的回答施加了哪些限制。(请原谅我,但我假设这是一个家庭作业问题。)让我们假设练习的重点是开始递归思考。那么你想写一个这样的函数:

let move plane (x, y, z) = (( code goes here ))

对于递归思考,基本见解是平面是点列表,您希望对所有点执行相同的操作。因此,该函数的较低级别视图将如下所示:

let rec move point_list (x, y, z) = (( code goes here ))

现在,一个列表要么是空的,要么不是。你只需要弄清楚在每种情况下该怎么做。此外,当列表不为空时,只要您使用较小的列表调用它,您就可以递归地使用您自己的函数。

事实上,如果这个练习的目的不是学习递归思维,那么答案将完全不同。特别是,List模块中有一个功能可以很容易地解决问题。

更新

显然你想以非递归方式解决问题。为了说明这是如何工作的,这里有一个函数,它接受两个点并将两个点的 x、y 和 z 坐标加 1:

let add1 [(x1, y1, z1); (x2, y2, z2)] =
    [(x1 + 1, y1 + 1, z1 + 1); (x2 + 1, y2 + 1, z2 + 1)]

这将导致编译器警告,因为它对于许多可能的输入都失败了。特别是,当列表中的点数不是 2 时,它就会失败。为了消除警告,我们需要决定要为这些情况返回什么。假设在这些情况下我们总是返回未更改的列表。然后我们得到以下信息:

let add1 = function
    | [(x1, y1, z1); (x2, y2, z2)] ->
        [(x1 + 1, y1 + 1, z1 + 1); (x2 + 1, y2 + 1, z2 + 1)]
    | pts -> pts

我想你知道你想要什么,但这并不是特别惯用的 OCaml。

另一种非递归(没有rec)解决问题的方法是使用List模块中的函数。那会更惯用,实际上这可能是我在现实世界中会做的事情。

于 2013-04-06T15:41:29.927 回答