number_in_month 练习(SML 列表迭代) [英] number_in_month exercise (SML list iteration)

查看:20
本文介绍了number_in_month 练习(SML 列表迭代)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to take a list of dates and a list of months and get a total count of the amount of dates that are in any of the months listed. Thus returning a single integer

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

I had a previously defined number_in_month function which takes in a list of dates and a single month and returns the amount of dates that fall in that month. It has been tested and works correctly. I use this as the foundation for the latter function. I've traced through the number_in_months function many times and I can't seem to find out whats wrong but it is simply not yielding the right answer

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

推荐答案

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

As you have stated, you just have to use the previous function number_in_month. Remembering that number_in_month takes a list of dates and a single month, and returns the number of matching months in the list of dates. Thus All there is needed to create number_in_months, is to call number_in_month for each element in the new list of months, with the original list of dates to be checked.

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

Such a solution could look like

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

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

However when you use pattern matching, you can shorten it down and make it even more readable

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

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

There is absolutely no reason for creating a count function, carrying around a "state". This seems to be your imperative mind, at play :) Take for example this simple function which will sum all element of a list

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

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

or even creating a length function (which is actually similar to your count function)

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

与其重复很多已经提到过很多次的好东西,我鼓励你去阅读这些问题及其答案.

Instead of repeating a lot of good stuff already mentioned so many times, I encouraging you to go read these questions and their answers.

更新

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

I also wanted to show you how to format you code in a better way

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 始终是我来自哪里的一场激烈争论.就我个人而言,我避免使用它们,而是使用用例,但我想您将来会倾向于使用它.

How to format nested if's is always a great debate where I'm from. Personally I avoid them, and use cases instead but I guess you will lean about that in the future.

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

However I also spotted a mistake in your count function. When you test whether your second argument (in both of your count functions) are the empty list with null, you do it on the tail of the argument, which will fail if the argument is in fact the empty list

- null (tl []);

uncaught exception Empty

例如这个输入

- number_in_months ([(1,1,1)], [1]);

uncaught exception Empty

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

Also your logic in number_in_month is wrong, as you are testing for the head of the datelist being equal to month, however your to count in either case uses the whole of datelist instead of its tail. This is seen as the below should not return 2 as a result

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

此错误是唯一使 number_in_month 函数不抛出异常的原因.

This error, is the only thing that is making the number_in_month function not throwing up an exception.

这篇关于number_in_month 练习(SML 列表迭代)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆