【问题标题】:Function only deletes one of many occurrences of a list函数仅删除列表的多次出现之一
【发布时间】:2016-01-02 02:17:49
【问题描述】:

我正在编写一个使用一个列表作为事件的函数。然后该函数获取此列表并从另一个列表中删除所有出现的它。

例如:

[1,2,3] 应该从 [3,2,1,2,3,1,2,3] 中删除,从而得到 [3,2]

[1,2,3] 不应该被删除,因为我会得到一个空列表 []

到目前为止,我已经将其删除所有事件之一,但不会删除任何其他事件。

这是我的功能:

fun deleteAll l1 [] = []
  | deleteAll l1 (hd::tl) =
      if starts l1 (hd::tl)
      then (deleteAll l1 tl; delete l1 (hd::tl))
      else [hd]@deleteAll l1 tl;

以下是其中使用的其他函数:

fun starts [] l2 = true
  | starts l [] = false
  | starts (h1::t1) (h2::t2) = (h1=h2) andalso (starts t1 t2);

fun delete l1 [] = []
  | delete l1 (hd::tl) =
      if starts l1 (hd::tl)
      then List.drop(hd::tl, length l1)
      else [hd]@delete l1 tl;

【问题讨论】:

  • 请记住,您不是在使用可变数据进行编程; deleteAll l1 tl; delete l1 (hd::tl) 等价于 delete l1 (hd::tl)
  • @molbdnilo 那么我该如何克服这个问题来解决我的问题呢?

标签: sml smlnj


【解决方案1】:

在进行类似的高级操作之前,首先实现一个更简单的案例,即删除每个给定元素出现的函数。 此后,您可以将此函数用作实现下一个功能的工具,即从另一个列表中删除一个列表中出现的每个元素。

我敦促您专心致志,不要看解决方案。这里有更多细节:SML List Deletion

解决方案:

关于第一个你可以这样做:

fun del e [] = []
  | del e (h::t) =
      if e=h
      then del e t
      else h :: (del e t);

关于第二个,你会这样实现:

fun delete _ [] = []
  | delete [] l2 = l2
  | delete (h1::t1) t2 = delete t1 (del h1 t2);

或者,您也可以使用内置函数(例如过滤器)代替第一个函数。

【讨论】:

  • 有什么方法可以使用我之前做的功能吗?
  • 恐怕不是因为函数start 只会确定给定列表中是否存在子集。对于诸如delete [4,6,5] [1,2,3,4,6,6,6,6,6,6,6,7,8,5];这样的情况,您怎么可能求助于类似的东西?子集 [4,6,5] 不存在,而您希望消除每次出现的 4、6 和 5。完全不同的两件事。
  • 实际上不,我希望删除每个出现的 [4,6,5],而不是单个元素!
  • 正是我所说的。你想让delete [4,6,5] [1,2,3,4,6,6,6,6,6,6,6,7,8,5]; 评估为[1,2,3,7,8],那么你怎么能应用像start 这样的函数来实现呢?
  • 我希望 deleteAll [1,2,3] [3,2,1,2,3,2,1,2,3] 评估为 [3,2,2]... 我只想删除 整个列表(子集列表)的所有出现,而不仅仅是单数项目。
猜你喜欢
  • 1970-01-01
  • 2016-01-09
  • 2017-05-29
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
  • 2015-05-30
  • 1970-01-01
  • 2016-08-25
相关资源
最近更新 更多