如何比较和搜索列表中的元素与列表 SML 中的元组

Posted

技术标签:

【中文标题】如何比较和搜索列表中的元素与列表 SML 中的元组【英文标题】:How to compare and search for an element in a list with a tuple inside a list SML 【发布时间】:2021-11-01 05:02:18 【问题描述】:

我想在元组列表中的每个第二个元素中使用searchingElements 列表进行搜索,并计算在测试中显示的元组列表中的列表中是否有月份,我不知道它是否应该通过递归来完成,我不知道如何在这里使用。

fun number_in_months(months : (int * int * int) list, months2 : (int * int * int) list, 
                      months3 : (int * int * int) list, searchingElements : int list) =
    

  if #2 (hd (tl months)) = (hd searchingElements)
  then
    1 
  else
    0

val test3 = number_in_months ([(2012, 2, 28), (2013, 12, 1), (2011, 3, 31), (2011, 4, 28)], [2, 3, 4]) = 3

我得到了这 2 个错误,后来我明白了我无法在列表和元组列表之间进行比较

(fn 1=1,... => 1) (hd number)
  main.sml:30.2-30.30 Error: operator and operand do not agree [overload - bad instantiation]
  stdIn:2.1-2.5 Error: unbound variable or constructor: fun3

【问题讨论】:

显示的代码格式非常糟糕的事实并没有帮助。但是解开它,我认为这里一定缺少一些东西。 fun3 从未使用过,并且不是递归的。 number_in_months 从未定义。您引用的错误中显示的代码在此之前从未显示过。如果对您的尝试没有更全面的了解,将很难为您提供帮助。 假设给你测试代码,你应该编写一个名为“number_in_months”的函数,它需要两个列表,而不是一个名为“fun3”的函数需要四个。 顺便说一句:我怀疑这个特定练习的要点之一是它会变得非常复杂和困难,除非您将其划分为您通过辅助函数解决的子问题。 另外:越早适应模式匹配越好。 抱歉,我在编译器本身中测试代码并尝试测试许多值,所以我没有关注代码结构,但我自己编辑了代码 【参考方案1】:

如果我们阅读函数代码和测试真的会产生误导,因为它们最初的类型不一致。

如果我遵循测试功能是

val test3 = number_in_months ([(2012,2,28),(2013,12,1),(2011,3,31),(2011,4,28)],[2,3,4]) = 3

那么number_in_months的类型应该是

val number_in_months = fn: ('a * ''b * 'c) list * ''b list -> int

这是一对(2元组)和应该实现逻辑的函数

fun fun3 (months :(int*int*int) list, months2: (int*int*int) list, months3: 
 (int*int*int) list, searchingElements: int list)

实际上是一个带有参数的函数,它是一个 4 元组,并且不匹配是显而易见的。此外,参数months2months3 也不会在任何地方使用。另外,每个所谓的months 参数本身都是列表类型。此外,除了test3这一行,没有什么有意义的东西可以用来回答甚至是回复。

但是,在 test3 行之后,我尝试编写一个至少可以完成任务的函数,如下所示:

fun number_in_months (date_triples, months) =
    let
      fun is_second_of_any_triple ele = List.exists (fn (_, x, _) => x = ele)
    in
      List.foldl (fn (curr, acc) => if is_second_of_any_triple curr date_triples then acc + 1 else acc) 0 months
    end

【讨论】:

编写一个函数 number_in_months ,它接受一个日期列表和一个月份列表(即一个 int 列表),并返回日期列表中任何月份中的日期数月份列表。假设月份列表没有重复的数字。 这就是程序应该是什么,我只是怀疑测试用例中是否会有超过3个元组列表以及如何检查元组列表的月份是否存在于列出并迭代列表中的每个元素,我没有其他参数,因为不手动检查元素会很愚蠢 我编写的函数应该适用于任何形式为 test3 行的输入。问题是,函数定义和函数应用不是类型一致的,总是会失败。定义需要 4 元组,但应用程序是 2 元组。分享一些我写的上面的函数会失败的测试用例。然后我可以提供更多帮助,因为这应该可以帮助我更好地理解你的问题。 它工作得很好,请问您是否有另一种原始方法来解决这个问题?这对我来说有点复杂,因为代码中的这些东西以前没有见过,很多问题看起来像 number_in_months 问题 这是非常复杂的代码,但在课程中我之前没有看到这样的代码,所以我只是想知道是否还有另一种具有递归的解决方案,并提前致谢【参考方案2】:

具有显式递归的版本:

假设我们有一个函数可以计算元组列表中单个数字的出现次数;

month_occurrences: ((int * int * int) list * int) -> int

然后我们可以对数字列表进行递归,边加边加:

fun number_in_months(dates, []) = 0
  | number_in_months(dates, m::ms) = month_occurrences(dates, m) + number_in_months(dates, ms)

而带有直接递归的month_occurrences 可能看起来像

fun month_occurrences([], _) = 0
  | month_occurrences((_, m, _)::ds, m') = (if m = m' then 1 else 0) + month_occurrences(ds, m')

【讨论】:

它也可以,请问我们如何定义日期然后我们将它们定义为元组列表 如果您询问第一个函数的 dates 参数,标识符是匹配任何内容的模式,因此它可以匹配元组列表。 (并且“两个”参数实际上只是一个,这是一对模式匹配的。)

以上是关于如何比较和搜索列表中的元素与列表 SML 中的元组的主要内容,如果未能解决你的问题,请参考以下文章

给定 SML 中的变量列表,生成所有真值赋值的列表?

如何从 C# 中的元组列表中获取最接近“a”的 4 个元素?

python的元组和列表的区别

为啥 foldl 签名是管道而不是 SML 中的元组类型?

列表理解列表中的元组列表

python中的元组和列表有啥区别,哪个更有效[重复]