【问题标题】:Writing power function in Standard ML with a predefined compound function使用预定义的复合函数在标准 ML 中编写幂函数
【发布时间】:2018-08-11 18:25:33
【问题描述】:

在标准 Ml 中编写幂函数时遇到问题。我正在尝试编写一个名为exp 的函数,类型为int -> int -> int

应用程序exp b e,对于非负的e,应该返回b^e

例如,exp 3 2 应该返回 9。exp 必须使用下面提供的函数 compound 来实现。 exp 不应该直接调用自己。这是compound 函数,它接受一个值n、一个函数和一个值x。它所做的只是将函数应用于值 x n 次。

fun compound 0 f x = x 
  | compound n f x = compound (n-1) f (f x);

我很难弄清楚如何在没有递归的情况下编写这个函数,并且必须使用一个只能使用一个参数的函数的函数。任何人都知道从哪里开始?

这就是我所拥有的:

fun exp b 0 = 1  
  | exp b e = (compound e (fn x => x*x) b)  

我知道这行不通,因为如果我输入 2^5 它会: 2*2、4*4、16*16等。

【问题讨论】:

  • compound 递归调用自己...我编辑了问题以使其符合您的意思。
  • 函数复合允许递归,但函数exp不允许递归。

标签: sml ml mosml


【解决方案1】:

这可能不是 100% 正确的代码。我刚刚阅读了一些标准 ML 文档并获取了一些代码并为您的示例重新编写了它,但大多数编程语言的总体思路是相同的。

fun foo (num, power) =
let
  val counter = ref power
  val total = 1
in
  while !counter > 0 do (
    total := !total * num
    counter := !counter - 1
  )
end;

用一些伪代码更清楚:

input x, pow
total = 1
loop from 1 to pow
  total = total * x
end loop
return total

这不处理负指数,但它应该让你开始。

它基本上是一个简单的指数算法:重复乘法。

2^4 = 1*2*2*2*2 //The 1 is implicit
2^0 = 1

【讨论】:

  • OP 要求使用上面列出的compound 函数。
  • 我遇到的主要问题是如何保留原始基数 b 并将其用于乘法。我觉得我必须使用多次调用来复合,但不知道该怎么做。
  • 我也是这么想的。基本上将乘法分解为加法。 2^4 = 2*2*2*2 = 2+2+2+2+2+2+2+2。 3^5 = 3*3*3*3*3 = 3+3...+3
  • 不幸的是,我不得不退出,所以我无法继续工作,但希望它能给你一个想法
【解决方案2】:

你非常接近。您对 exp 复合 fn x => x*x 的定义(正如您所注意到的)不是您想要的,因为它反复平方输入。相反,您想要重复 乘以基数。即fn x => b*x

接下来,您实际上可以删除 e = 0 的特殊情况,依靠 compound 在被要求应用函数 0 次时“做正确的事情”这一事实。

fun exp b e = compound e (fn x => b*x) 1

【讨论】:

  • 我是否可以发送一个元组给化合物,以便同时发送 x 的基数和值?
  • 基础不会随着迭代而改变,所以不需要!完全按照我在答案中所做的那样编写函数是正确的。有关更多信息,您可能有兴趣阅读 closures
  • 这么小的事情就说得通了!谢谢!
  • 没问题。我也刚刚用一个解决方案编辑了答案,消除了e = 0 时的特殊情况,使最终代码非常优雅。
【解决方案3】:

我相信你可以这样做

  fun exp 0 0 = 1
  | exp b 0 = 1
  | exp b e = (compound (e - 1) (fn x => b * x ) b); 

【讨论】:

    猜你喜欢
    • 2020-12-17
    • 2018-08-23
    • 2022-01-12
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 2012-04-13
    相关资源
    最近更新 更多