1

我在 SML 中遇到了函数问题。此函数应返回不会求和但被求和的数字的列表索引。函数调用: index(10, [1,2,3,4,5,6,7]) 结果应该是 3(10 是数字的总和,我们从列表中寻找一个索引,它给我们 10, eg: 1+2+3=6, 1+2+3+4=10, 返回前一个)

fun index (sum : int, numbers : int list) =
    if null numbers
    then 0
    else if hd(numbers) > sum
    then 0
    else 1 + index(sum, (hd(numbers)+(hd(tl numbers)))::(tl numbers))

它似乎有效,但结果是错误的。函数每两次调用都会增加结果,即使它不应该。谁能告诉我如何解决这个问题?

4

2 回答 2

2

你需要保留一个计数器和总数。每次递归调用都会递增的计数器,总和等于每个 hd(numbers) 的总和,然后在总和 > 时返回计数器。

像这样的东西;

if (total + hd numbers) >= sum
then counter
else recursivecall(total + hd numbers, tl numbers, counter + 1)
于 2013-10-14T05:49:53.560 回答
2

您快到了。虽然我同意@koodawg 的观点,即添加计数器和运行总计是解决此问题的另一种解决方案,但在您的代码中包含这些会使它变得比需要的更复杂。

首先,我对您的代码有一些评论。您必须删除不必要的括号。hd(numbers)等于hd numbers(hd(tl numbers))等于hd(tl numbers)。所以你(hd(numbers)+(hd(tl numbers)))可以简化为(hd numbers + hd(tl numbers)). 此外,您可以将if null numbers和组合if hd(numbers) > sum在一个条件中以简化代码,因为它们会产生相同的结果:0.

我将尝试解释代码是如何工作的,我希望您能明白必须修改代码的地方。

使用您的示例,index(10, [1,2,3,4,5,6,7])的代码执行将如下所示:

1)

 fun index(10, [1,2,3,4,5,6,7]) =
     if 1 > 10 
     then 0 
     else 1 + (10, [1 + 2] append to [2,3,4,5,6,7]) 

新列表: [3,2,3,4,5,6,7]
结果: 1

2)

 fun index(10, [3,2,3,4,5,6,7]) =
     if 3 > 10 
     then 0 
     else 1 + (10, [3 + 2] append to [2,3,4,5,6,7]) 

新列表: [5,2,3,4,5,6,7]
结果: 1

3)

 fun index(10, [5,2,3,4,5,6,7]) =
     if 5 > 10 
     then 0 
     else 1 + (10, [5 + 2] append to [2,3,4,5,6,7]) 

新列表: [7,2,3,4,5,6,7]
结果: 1

4)

 fun index(10, [7,2,3,4,5,6,7]) =
     if 7 > 10 
     then 0 
     else 1 + (10, [7 + 2] append to [2,3,4,5,6,7]) 

新列表: [9,2,3,4,5,6,7]
结果: 1

5)

 fun index(10, [9,2,3,4,5,6,7]) =
     if 9 > 10 
     then 0 
     else 1 + (10, [9 + 2] append to [2,3,4,5,6,7]) 

新列表: [11,2,3,4,5,6,7]
结果: 1

6)

 fun index(10, [11,2,3,4,5,6,7]) =
     if 11 > 10 
     then 0 

结果: 0

总结所有结果: 1 + 1 + 1 + 1 + 1 + 0 = 5 (就像您所说的那样,您的函数将 2 添加到预期结果中)

正确的代码必须如下所示:

1)

 fun index(10, [1,2,3,4,5,6,7]) =
     if 1 > 10 
     then 0 
     else 1 + (10, [1 + 2] append to [3,4,5,6,7]) 

新列表: [3,3,4,5,6,7]
结果: 1

2)

 fun index(10, [3,3,4,5,6,7]) =
     if 3 > 10 
     then 0 
     else 1 + (10, [3 + 3] append to [4,5,6,7]) 

新列表: [6,4,5,6,7]
结果: 1

3)

 fun index(10, [6,4,5,6,7]) =
     if 6 > 10 
     then 0 
     else 1 + (10, [6 + 4] append to [5,6,7]) 

新列表: [10,5,6,7]
结果: 1

4)

 fun index(10, [10,5,6,7]) =
     if 10 > 10 
     then 0

结果: 0

总结所有结果:1 + 1 + 1 + 0 = 3 这是预期的答案。

提示:您始终确保您的函数正在处理的新列表必须小于以前的列表/原始列表。

我希望我清楚地解释了为什么您的代码不起作用。我没有包含代码,因为我知道这是在线课程的作业。

于 2013-10-20T04:45:49.610 回答