【问题标题】:Matching a Finite Range of Elements with Patterns将有限范围的元素与模式匹配
【发布时间】:2011-08-19 13:12:28
【问题描述】:

在处理我对这个question 的回答时,我想到很难匹配有限范围的元素。使用内置模式,您可以匹配 1 个元素 (_)、1 个或多个元素 (__) 或零个或多个元素 (___)。为了匹配多个元素,我使用了PatternSequence,就像这样

a:PatternSequence[_,_,_]

或者,更一般的

a:PatternSequence@@Array[_&,3].

(使用 Condition 也可以。)我们可以匹配 n 到 m 个元素的范围

a:Alternatives@@( PatternSequence @@@ Array[_&, {n,m}] ),

但这是一种相当复杂的方式来完成可以由以下人员完成的事情

a__ /; n <= Length[{a}] <= m.

然而,这带来了一个有趣的问题,使用Condition 形式可以直接匹配范围 0 到 n,

a___ /; Length[{a}] <= n,

但这是否可以单独使用模式来完成,即不使用Condition (/;)?更具体地说,如何在不添加条件的情况下匹配 0 个元素?还有,哪个更快?

【问题讨论】:

    标签: wolfram-mathematica


    【解决方案1】:

    也许你可以用Repeated 做点什么。例如

    Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1,2}}, {Repeated[_, {2, 4}]}]
    

    给出与

    相同的结果
    Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1,2}}, {a___ /; 2 <= Length[{a}] <= 4}]
    

    第一种方法似乎比第二种方法快。例如

    tab = Table[Range[RandomInteger[1000]], {1000}];
    Timing[t1 = Cases[tab, {a___ /; 0 <= Length[{a}] <= 100}];]
    Timing[t2 = Cases[tab, {Repeated[_, {0, 100}]}];]
    SameQ[t1, t2]
    

    返回我的系统

    {0.027801, Null}
    
    {0.000733, Null}
    
    True
    

    【讨论】:

    • +1,我从没想过要看看RepeatedFullForm。它的表现完全符合我的预期。我会等着看有没有其他答案。
    • +1 我也是。对旧功能和基本功能的更新通常非常有用,但可能会被忽视多年。我记得在 TableDo 中添加了 {i,{2,8,34,3.5,6}} 类型的索引规范。在我偶然发现这个非常有用的功能之前,它一定已经存在多年了。但是,如果您已经使用了很长时间,谁会查找 Table
    • +1 我使用Repeated 足够多,因此我有一个自定义符号。我输入这个模式:Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1, 2}}, {_ .. {2, 4}}]_后面的空格是必需的)。坦率地说,我不知道为什么默认情况下没有这样的东西。
    • @rcollyer 我的意思是,我使用了 Notations 包/调色板来创建一个符号,这样我的评论中的行就相当于上面帖子中的顶部代码行。我已经使用它好几年了,虽然我不能排除与其他编码风格不兼容的可能性,但据我所知,我还没有遇到过问题。
    • @Mr.Wizard,啊。我明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 2022-01-16
    • 1970-01-01
    • 2016-07-02
    • 2015-03-22
    • 1970-01-01
    相关资源
    最近更新 更多