【问题标题】:SML/NJ searching in list of tuples of listSML/NJ 在列表的元组列表中搜索
【发布时间】:2018-03-19 13:12:33
【问题描述】:

我对 SML/NJ 很陌生,有点迷茫。我一直在尝试实现一个函数,该函数将搜索包含一些列表的元组列表,例如:

val x = [(5, 2, [9 , 8, 7]), (3, 4, [6, 5, 0]), (11, 12, [8, 3, 1])] 

一旦我的目标数字与元组元素 3 中的数字匹配,我希望我的函数将元组的第一个元素添加到新列表中。我已经尝试了几种实现,但到目前为止它们都不能正常工作。

type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;
val a: int list = nil;

fun findNum(nil) = a | findNum (x: id list) =
    let val tem = hd(x)
        val theList = #3tem
        val i = #1tem
        fun findMatch(nil) = a | findMatch(tem) =
            if (number = hd(theList)) then i::a 
            else findMatch (tl(theList))
    in findNum(tl(x))
    end;

 findNum(b);

我知道它写得不好,这就是为什么它总是返回一个空列表。我觉得我需要做“if else”而不是 let/in/end 所以它会递归地调用列表中的其余元组。我的问题是我不知道该怎么做,因为如果我使用 if/else 那么我不能在函数中声明一些值。我感谢任何建议或提示。

谢谢。

【问题讨论】:

  • 您能否添加一个输入和所需输出的简单示例,例如输入[(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])] 您期望什么输出?
  • 一旦第三个元素中的数字匹配,我希望它返回元组的第一个元素列表。所以在这种情况下应该是 [5, 11 ]。
  • 非常感谢。
  • 什么是“新名单”?这就是你所说的函​​数的结果值吗?
  • 是的,我的意思是函数的结果值列表。

标签: sml smlnj


【解决方案1】:

如果x 是列表xs 中的一个元素,则可以从函数member (x, xs) 开始:

fun member (x, xs) = List.exists (fn y => x = y) xs

基本情况是三元组列表为空时。那么x 不会出现在任何(不存在的)三元组的第三个元素中,结果列表为空。通过模式匹配列表的第一个元素是三元组(i,j,xs) 和列表的尾部ts 并询问x 是否是第三个元素@ 的成员来实现递归案例987654329@;如果是,则返回元组的第一部分,i

fun find (x, []) = []
  | find (x, (i,j,xs)::ts) =
    if member (x, xs)
    then i :: find (x, ts)
    else find (x, ts)

使用高阶列表组合 mapfilter 的较短版本:

fun find (x, ts) = map #1 (filter (fn (i,j,xs) => member (x, xs)) ts)

【讨论】:

  • 非常感谢您的帮助和解释。这个实现非常简洁。
【解决方案2】:

这是我的实现,有一些细微的变化:

type id = int* int* int list;
val b:id list = [(5,2,[9,8,7]), (3,4,[6,5,0]), (11, 12, [8,3,1])]
val number: int = 8;

fun findNum [] = [] 
  | findNum (x::xs)  =
        let 
           val theList :int list = #3 (x :id)
           val i : int = #1 x
           fun findMatch [] = false
             | findMatch (y::ys) = if (number = y) then true
                                   else findMatch ys
        in 
           if (findMatch theList = true) then i ::(findNum xs) 
           else (findNum xs) 
        end;

例子:

- findNum b;
val it = [5,11] : int list

【讨论】:

  • 太棒了。非常感谢。
  • 您的 if-then-elses 可以缩短一点。 if (number = y) then true else findMatch ys 等价于 number = y orelse findMatch ys。同样,if (findMatch theList = true) then ... 可以缩短为if findMatch theList then ...
  • @SimonShine,谢谢!!!,我不太确定,因为我没有 sml 方面的经验,感谢您的有用评论!!
猜你喜欢
  • 2015-07-06
  • 1970-01-01
  • 2014-05-23
  • 2021-11-01
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
相关资源
最近更新 更多