【问题标题】:How to return item index from list SML?如何从列表 SML 返回项目索引?
【发布时间】:2013-10-20 18:09:05
【问题描述】:

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

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

【问题讨论】:

    标签: list sml


    【解决方案1】:

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

    首先,我有一些关于您的代码的问题。您必须删除不必要的括号。 hd(numbers)hd numbers 相同,(hd(tl numbers)) 等于 hd(tl numbers)。所以你的(hd(numbers)+(hd(tl numbers))) 可以简化为(hd numbers + hd(tl numbers))。此外,您可以将 if null numbersif 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 这是预期的答案。

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

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

    【讨论】:

      【解决方案2】:

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

      类似的东西;

      if (total + hd numbers) >= sum
      then counter
      else recursivecall(total + hd numbers, tl numbers, counter + 1)
      

      【讨论】:

      • 这是否意味着'else if'语句'或'else'语句是错误的?
      • 返回 0 表示列表为空肯定是错误的,因为索引 0 也指列表中的第一个数字。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      • 2018-07-02
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-02-12
      • 1970-01-01
      相关资源
      最近更新 更多