如何在没有库函数的情况下用ocaml中的大整数实现乘法运算?

时间:2011-10-22 18:59:00

标签: ocaml

我目前正在尝试使用Ocaml中没有库函数的大整数实现乘法。

这是我到目前为止所做的:

let rec mulByDigit i l = 
  match l with
    [] -> []
  | h::t -> 
      match t with
        [] -> [(h*i) mod 10]
      | x::y -> 
          match y with
            [] -> [x*i/10+(h*i) mod 10]@mulByDigit i t
          | a::b -> [(x*i/10+(h*i)mod 10+(a*i/10+(x*i) 
                             mod 10)/10) mod 10]@mulByDigit i t

对于i = 9和l = [9; 9; 9; 9]给出了[9; 9; 9; 1]当需要的是[8; 9; 9; 9; 1]

据我了解,其算法是从最后一位* i,当前数字* i和下一位* i获取信息,以构建答案列表的当前数字。然而,有两种情况并非如此。对于答案列表的第一个数字和最后一个数字,最后一个数字取自输入列表的当前数字* i和前一个数字* i的信息,第一个数字取自当前数字* i和后续数字的信息*我的输入列表。我可以处理最后一个数字的特殊情况,因为最后一个数字与[]的匹配,但我无法弄清楚如何为第一个数字做特殊情况,因为我没有看到任何条件我可以放入if then语句仅在此函数的初始调用时发生。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:3)

嗯,这听起来有点像家庭作业问题。以下是一些观察结果。

如果您使用列表顶部的单位数字而不是尾部表示您的数字,您可能会看到更漂亮的代码。您通常希望处理从单位结束开始的事情,并且它具有数学上的正确性(列表中第n个位置的乘数为10 ** n)。但也许你无法掌控自己的代表性。

在一般情况下,你有一个随身携带。如果你认为你的内部函数有三个输入(大数字的下一个数字,整数乘以,携带)你可能会使事情有效。

你绝对不想在第一次调用它们时考虑做出不同的功能!这不是一个功能,这是必要的编程。

此致

答案 1 :(得分:1)

我会考虑以不同的方式打破这种情况。例如,你可以编写一个函数,它只是乘法而不用担心携带,然后是第二个处理携带的函数。

正如杰弗里建议的那样,你也可以通常或者根据需要反转数字。虽然您可能不允许使用List.reverse函数,但您可以在大约一行代码中自行实现。

哦,为了提高效率和/或良好的习惯,你应该重写那些说[one value]@list代替(one value)::list的部分。他们会做同样的事情,第二个会比第一个更快(除非编译器足够聪明,可以为你做这个替换,它可能是,在这种情况下,它将是相同的速度)。