【问题标题】:number_in_month exercise (SML list iteration)number_in_month 练习(SML 列表迭代)
【发布时间】:2013-01-23 01:12:14
【问题描述】:

我需要获取日期列表和月份列表,并计算列出的任何月份中的日期总数。因此返回一个整数

我有一个先前定义的 number_in_month 函数,它接收一个列表 日期和一个月,并返回该日期的数量 月。它已经过测试并且可以正常工作。我以此为基础 后一个功能。我已经跟踪了很多 number_in_months 函数 多次,我似乎无法找出问题所在,但它根本没有给出正确的答案

fun number_in_month (datelist : (int*int*int)list, month : int)  = 

let
fun count(x : int , datelist : (int*int*int)list)=
if null (tl datelist)
then x
else if #2(hd datelist) = month
then count(x+1, tl datelist)
else count(x, tl datelist)

in

if #2(hd datelist) = month
then count(1, datelist)
else count(0, datelist)

end
fun number_in_months (datelist : (int*int*int)list, monthlist : (int)list)=
let 
fun count(x : int, monthlist : (int)list)=
if null (tl monthlist)
then x
else count((x + number_in_month(datelist, hd monthlist)), tl monthlist) 

in
count (( number_in_month(datelist, hd monthlist), tl monthlist))
end

【问题讨论】:

    标签: list date iteration sml


    【解决方案1】:

    正如你所说,你只需要使用前面的函数number_in_month。请记住,number_in_month 需要一个日期列表和一个月份,并返回日期列表中匹配的月份数。因此,创建number_in_months 所需要做的就是为新月份列表中的每个元素调用number_in_month,并检查原始日期列表。

    这样的解决方案可能看起来像

    fun number_in_months (dates, months) =
        if null months then
          0
        else
          number_in_month(dates, hd months) + number_in_months(dates, tl months)
    

    但是,当您使用模式匹配时,您可以将其缩短并使其更具可读性

    fun number_in_months (dates, []) = 0
      | number_in_months (dates, d::ds) =
          number_in_month(dates, d) + number_in_months(dates, ds)
    

    绝对没有理由创建一个带有“状态”的count 函数。这似乎是你的当务之急,在玩:) 以这个简单的函数为例,它将对列表的所有元素求和

    fun sum [] = 0
      | sum (x::xs) = x + sum xs
    

    甚至创建一个长度函数(实际上类似于您的计数函数)

    fun length [] = 0
      | length (x::xs) = 1 + length xs
    

    我鼓励你去阅读这些questions 和他们的答案,而不是重复很多已经提到的好东西。

    更新

    我还想向您展示如何以更好的方式格式化您的代码

    fun number_in_month (datelist : (int*int*int) list, month : int)  =
        let
          fun count (x : int , datelist : (int*int*int) list) =
              if null (tl datelist)
              then x
              else if #2(hd datelist) = month
                then count (x+1, tl datelist)
                else count (x, tl datelist)
        in
          if #2(hd datelist) = month
          then count (1, datelist)
          else count (0, datelist)
        end
    
    
    fun number_in_months (datelist : (int*int*int) list, monthlist : int list)=
        let
          fun count (x : int, monthlist : int list)=
              if null (tl monthlist)
              then x
              else count (x + number_in_month(datelist, hd monthlist), tl monthlist)
        in
          count (number_in_month (datelist, hd monthlist), tl monthlist)
        end
    

    如何格式化嵌套的 if 始终是我来自哪里的一场激烈争论。就我个人而言,我避免使用它们,而是使用用例,但我想您将来会倾向于使用它。

    不过,我也发现您的计数功能有一个错误。当您测试您的第二个参数(在您的两个计数函数中)是否是带有null 的空列表时,您在参数的尾部执行此操作,如果参数实际上是空列表,则会失败

    - null (tl []);
    
    uncaught exception Empty
    

    例如这个输入

    - number_in_months ([(1,1,1)], [1]);
    
    uncaught exception Empty
    

    您在number_in_month 中的逻辑也是错误的,因为您正在测试datelist 的头部是否等于month,但是您对count 在任何一种情况下都使用整个datelist 而不是它的尾巴。这被视为下面不应返回 2 作为结果

    - number_in_month([(1,1,1), (2,2,2), (3,3,3)], 1);
    val it = 2 : int
    

    这个错误是唯一使number_in_month 函数不抛出异常的原因。

    【讨论】:

    • 哇,我不敢相信它这么简单。非常感谢
    • 我已经更新了答案,提供了一些关于如何摆脱计数功能的示例以及一些您应该阅读的建议问题/答案。
    • 在你的代码中发现了一些错误,同时试图给出一个应该如何缩进的例子。但是,如果您发现这是对您问题的回答,您可能不想接受它。
    • 你太棒了。感谢您的彻底回复
    • @AndrewMcLaughlin,如果您接受答案,您可能会发现将来人们更愿意回答您的问题,您会找到最好的。 Click the check mark next to the answer, below the up/down vote buttons.
    【解决方案2】:

    您的代码的问题是,如果最后日期与月份匹配,则您没有计算最后日期。这段代码运行良好。

    fun number_in_month (datelist : (int*int*int) list, month : int)  =
        let
          fun count (x : int , datelist : (int*int*int) list) =
              if null (tl datelist)
              then 
                  if #2(hd datelist) <> month
                          then x
                         else x+1
             else if #2(hd datelist) = month
                then count (x+1, tl datelist)
                else count (x, tl datelist)
        in
              count (0, datelist)
        end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      相关资源
      最近更新 更多