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

查看:85
本文介绍了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测试第二个参数(在两个count函数中)是否为空列表时,请在参数的末尾进行操作,如果该参数实际上为空列表,则该操作将失败

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天全站免登陆