首页 > 解决方案 > 使用中缀运算符连接列表中的所有元素

问题描述

所以我有一个列表,可以说[t, f, f, t, f]和一个中缀运算符<==>。我想连接元素,因此最终结果将如下所示t <==> f <==> f <==> t <==> f。我遇到的问题是我得到了这个结果t <==> (f <==> (f <==> (t <==> f)))。我知道为什么会发生这种情况,因为 resursion 返回所有以前的元素,但我不知道如何解决它。

这是我的代码:

fun connect(l) =
    case l of
      x::[] => x
      | x::xs => x1 <==> connect(xs);

标签: smlsmlnj

解决方案


最终结果将如下所示t <==> f <==> f <==> t <==> f

问题是我得到了这个结果t <==> (f <==> (f <==> (t <==> f)))

x <==> y <==> z可能意味着(x <==> y) <==> z或者x <==> (y <==> z)

如果折叠到一侧有问题,请尝试折叠到另一侧:

fun connectLeft (x::xs) = foldl (op <==>) x xs
fun connectRight (x::xs) = foldr (op <==>) x xs

你可以看到是如何实现的foldlfoldr

或者您可以将折叠的插图视为结构转换(维基百科)。


编辑:假设x <==> y <==> z表示(x <==> y) && (y <==> z)

fun connect [] = ?
  | connect [x] = ?
  | connect [x,y] = x <==> y
  | connect (x :: y :: rest) =
      (x <==> y) && connect (y :: rest)
  • &&不是 SML 内置的逻辑与运算符的名称,称为andalso. 如果x <==> y返回 a bool,那么也许你的意思是在andalso这里使用。
  • 既然connect应该返回一个bool或一些用户定义的真实值,那么可能connect [x] = x,但可能不是。
  • 在任何情况下,connect []都应该考虑:这里是否有一个很好的默认值,以便函数不会在空列表上崩溃?

如果您想使用列表组合符(如map,foldl等)而不是手动递归来编写此代码,您可以做的是:

  1. 将输入列表转换为对列表,因此[x, y, z]变为[(x, y), (y, z)]。有一个名为 的 SML 函数zip,隐藏在库中ListPair……一些示例可能暗示如何执行此操作:

    ListPair.zip [x1,x2,x3] [y1,y2,y3] = [(x1,y1), (x2,y2), (x3,y3)]
    ListPair.zip [x1,x2,x3] [x1,x2,x3] = [(x1,x1), (x2,x2), (x3,x3)]
    ListPair.zip [x1,x2,x3] [y2,y3]    = [(x1,y2), (x2,y3)]
    
  2. 调用map (op <==>)对列表。

  3. 用一些运算符折叠结果&&


推荐阅读