【问题标题】:SML List DeletionSML 列表删除
【发布时间】:2016-01-01 01:15:47
【问题描述】:

我正在尝试编写一个函数来从另一个列表中删除一个列表。

''a list -> ''a list -> ''a list

这是我目前所拥有的:

fun delete  _ [] = [] | 
    delete (h1::t1) (h2::t2) = 
     if h1=h2
     then t2
     else h2::delete (h1::t1) t2;

我正在使用 MoscowML,它给了我一个警告:模式匹配不是详尽的错误。

上述功能的测试:

- delete [4,5] [1,2,3,4,5,6,7,8];
> val it = [1,2,3,5,6,7,8] : int list

想要的输出是:

> val it = [1,2,3,6,7,8] : int list

【问题讨论】:

    标签: sml smlnj ml


    【解决方案1】:

    这里有两个问题:

    1- 为什么解释器会发出警告:模式匹配不是详尽的错误

    2- 可以做些什么来使代码正常工作。

    关于第一点,警告的原因是因为您没有检查所有可能发生的可能性。函数delete 目前只检查两种可能性:

    -1 第二个列表是空列表(被模式覆盖:_ [] =

    -2 两个列表都不是空的(被第二个模式覆盖:(h1::t1) (h2::t2) =

    但是,还有第三种可能,即第一个列表是空列表。因此,以下输入会导致错误:delete [] [1,2,3,4,5,6]

    关于第二点,如果确切的要求是从第二个列表中连续删除第一个列表的元素并且只删除一次,那么您的解决方案非常接近。 else 分支很好,只有then 分支需要更多关注。 通过更正then 分支,我得到以下结果:

    delete [4,5] [1,2,3,4,5,6,7,8] = [1,2,3,6,7,8];
    delete [5,4] [1,2,3,4,5,6,7,8] = [1,2,3,4,6,7,8];
    delete [4,4,5] [1,2,3,4,5,6,7,8] = [1,2,3,5,6,7,8];
    delete [4,5,6] [1,2,3,4,5,6,7,8] = [1,2,3,7,8];
    delete [4,6,5] [1,2,3,4,5,6,7,8] = [1,2,3,5,7,8];
    delete [4,6,5] [1,2,3,4,6,7,8,5] = [1,2,3,7,8];
    

    但是,如果您想删除第一个列表中出现在第二个列表中的所有元素,而不管它们的顺序如何,那么您将需要重新考虑您的方法。

    例如,如果您想要以下结果:

    delete [4,6,5] [1,2,3,4,4,5,5,5,4,4,6,6,5,5,6,6,6,6,6,7,8,5] = [1,2,3,7,8];

    那么您需要分两步完成: 首先编写一个函数del,给定一个元素将删除列表中所有出现的元素:fun del e l = ... 其实现实际上与您为delete 提供的实现相同,只是您需要稍微更改then 分支。

    有了del之后,现在你可以实现函数delete,给定一个列表,它将删除第二个列表中该列表的所有出现。这里会用到之前定义的函数del

    【讨论】:

    • 感谢您的有趣回答!我最初的目标是按照与第一个列表相同的顺序删除元素,但现在这有助于我以不同的方式看待它。我设法通过更正“then”分支来修复代码!
    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 2021-06-26
    • 2021-03-25
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    相关资源
    最近更新 更多