将有限范围的元素与模式匹配

rco*_*yer 12 wolfram-mathematica

在研究我对这个问题的答案时,我想到很难匹配有限范围的元素.使用内置模式,您可以匹配1个元素(_),1个或多个元素(__)或零个或多个元素(___).为了匹配多个元素,我使用了PatternSequence,就像这样

a:PatternSequence[_,_,_]
Run Code Online (Sandbox Code Playgroud)

或者,更一般地说

a:PatternSequence@@Array[_&,3].
Run Code Online (Sandbox Code Playgroud)

(使用a Condition也可以.)为了匹配我们可以做的n到m个元素的范围

a:Alternatives@@( PatternSequence @@@ Array[_&, {n,m}] ),
Run Code Online (Sandbox Code Playgroud)

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

a__ /; n <= Length[{a}] <= m.
Run Code Online (Sandbox Code Playgroud)

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

a___ /; Length[{a}] <= n,
Run Code Online (Sandbox Code Playgroud)

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

Hei*_*ike 15

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

Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1,2}}, {Repeated[_, {2, 4}]}]
Run Code Online (Sandbox Code Playgroud)

给出了相同的结果

Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1,2}}, {a___ /; 2 <= Length[{a}] <= 4}]
Run Code Online (Sandbox Code Playgroud)

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

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]
Run Code Online (Sandbox Code Playgroud)

返回我的系统

{0.027801, Null}

{0.000733, Null}

True
Run Code Online (Sandbox Code Playgroud)