我有一个R3空间,我试图用OCAML函数来计算一些数学“问题”。
定义函数“move”,它根据plane_name(例如plane1)和vector(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)]
谢谢
答案 0 :(得分: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
模块中的函数。那将是更惯用的,事实上可能是我在现实世界中应该做的事情。