Mathematica 中 PatternTest 的意外行为

发布于 2024-12-20 22:48:36 字数 429 浏览 4 评论 0原文

我正在研究玩具问题,以帮助我吸收 Mathematica 中模式匹配的想法。下面的代码没有按照我的预期运行,我无法弄清楚我对 PatternTest 的理解有什么问题。

MatchQ[{2, 1, 2, 5}, {x__?(FromDigits[{#}] > 3 &), y__}]

我希望这段代码能够检查列表 {2,1,2,5} 是否可以写成两个连续的(非空)序列,这样我们从第一个序列得到的整数是由于 {Sequence[2,1],Sequence[2,5]} 是重写列表的一种方法,使得 FromDigits[{2,1}] > 大于 3。 3 成立,我希望该代码返回值 True。然而,事实并非如此。

我对代码的解释有什么问题吗?

I am working on toy problems to help me assimilate the idea of pattern matching in Mathematica. The following code does not behave as I expected, and I could not figure out what is wrong with my understanding of PatternTest.

MatchQ[{2, 1, 2, 5}, {x__?(FromDigits[{#}] > 3 &), y__}]

I expected this piece of code to check if the list {2,1,2,5} can be written as two consecutive (non-empty) sequences such that the integer we get from the first sequence is greater than 3. Since {Sequence[2,1],Sequence[2,5]} is one way to rewrite the list such that FromDigits[{2,1}] > 3 holds, I expected that code to return the value True. However, that is not the case.

What is wrong with my interpretation of the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

菩提树下叶撕阳。 2024-12-27 22:48:36

PatternTest (又名 ?) 的文档说

以诸如 __?test 的形式,序列中的每个元素都与 __ 匹配
应用测试时必须产生 True

因此,您的代码将不会按您希望的方式工作。

查看模式如何工作的一个好方法是使用 ReplaceList
与您的代码接近的内容是

In[1]:= ReplaceList[{3, 4, 2, 1}, 
          {___, x__?(FromDigits[{##}] > 3 &), y___} :> {{x}, {y}}]

Out[1]= {{{4}, {2, 1}}}

但是,如果您使用 Condition (/;) 代替模式测试,然后你就可以得到你正在寻找的行为

In[2]:= ReplaceList[{3, 4, 2, 1}, 
          {___, x__, y___} :> {{x}, {y}} /; FromDigits[{x}] > 3]

Out[2]= {{{3, 4}, {2, 1}}, {{3, 4, 2}, {1}}, {{3, 4, 2, 1}, {}}, 
         {{4}, {2, 1}}, {{4, 2}, {1}}, {{4, 2, 1}, {}}, {{2, 1}, {}}}

The documentation for PatternTest (aka ?) says

In a form such as __?test every element in the sequence matched by __
must yield True when test is applied.

Thus your code will not work as you hoped.

A good way to see how a pattern is working is to use ReplaceList.
Something close to your code is

In[1]:= ReplaceList[{3, 4, 2, 1}, 
          {___, x__?(FromDigits[{##}] > 3 &), y___} :> {{x}, {y}}]

Out[1]= {{{4}, {2, 1}}}

However, if you use Condition (/;) instead of pattern test, then you can get the behaviour that you were looking for

In[2]:= ReplaceList[{3, 4, 2, 1}, 
          {___, x__, y___} :> {{x}, {y}} /; FromDigits[{x}] > 3]

Out[2]= {{{3, 4}, {2, 1}}, {{3, 4, 2}, {1}}, {{3, 4, 2, 1}, {}}, 
         {{4}, {2, 1}}, {{4, 2}, {1}}, {{4, 2, 1}, {}}, {{2, 1}, {}}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文