【问题标题】:Regex for binary multiple of 33的二进制倍数的正则表达式
【发布时间】:2011-11-02 00:53:41
【问题描述】:

我想知道如何构造一个正则表达式来知道以 2 为底的数字(二进制​​)是否是 3 的倍数。我在这个线程中读过 Check if a number is divisible by 3 但他们不使用正则表达式,并且有人画的图是错误的(因为它不接受偶数)。我尝试过: ((1+)(0*)(1+))(0) 但它不适用于某些值。希望你能帮助我。

更新: 好的,谢谢大家的帮助,现在我知道如何绘制 NFA,这里我留下了图形和正则表达式:

在图中,状态是以 10 为底的模 3 数。

例如:要进入状态 1,你必须有 1,然后你可以加 1 或 0,如果你加 1,你将有 11(以 10 为底的 3),而这个数字 mod 3 是 0 那么你将圆弧绘制到状态 0。

((0*)((11)*)((1((00) *)1) *)(101 *(0|((00) *1 *) *0)1) *(1(000)+1*01)*) *

其他的正则表达式也可以,但它更短。

非常感谢:)

【问题讨论】:

  • 真的必须是正则表达式吗?检查可分性会更容易
  • 属于P还是NP问题?

标签: regex binary


【解决方案1】:

我知道这是一个老问题,但还没有给出有效的答案,并且这个问题首先出现在 Google 上的“二进制可被 3 正则表达式整除”。

基于作者提出的 DFA,可以通过简化二进制字符串通过 DFA 的路径来生成一个非常短的正则表达式。

最简单的,只使用状态A,是:

0*

包括状态B:

0*(11)*0*

包括状态C:

0*(1(01*0)*1)*0*

并且包括回到状态A后,整个过程可以重新开始。

0*((1(01*0)*1)*0*)*

使用一些基本的正则表达式规则,这可以简化为

(1(01*0)*1|0)*

祝你有美好的一天。

【讨论】:

  • 这应该是被选中的
【解决方案2】:

如果我可以为this code golf question 插入我的解决方案!它是一段 JavaScript 生成正则表达式(可能效率低下,但可以完成工作)以实现每个基的可分性。

这是它为以 2 为底的 3 整除而生成的:

/^((((0+)?1)(10*1)*0)(0(10*1)*0|1)*(0(10*1)*(1(0+)?))|(((0+)?1)(10*1)*(1(0+)?)|(0(0+)?)))$/

编辑:与 Asmor 相比,可能非常效率低下 :)

编辑 2:另外,这是 this question 的副本。

【讨论】:

  • 它涵盖了更多的案例!
【解决方案3】:

对于一些正在学习和搜索如何做到这一点的人:

  1. 观看此视频: https://www.youtube.com/watch?v=SmT1DXLl3f4&t=138s

  2. 写出状态方程并用 Axden 定理解决它们

  3. 图像结果中可以看到我所做的方式与用户@Kert Ojasoo 指出的相同。我希望我正确地做到了,因为我花了 2 天时间来解决它...

【讨论】:

  • 考虑到字符串可能很长并且重复(检查这个 Kata:codewars.com/kata/54de279df565808f8b00126a/train/java),完整的正则表达式应该是:^(1(01*0)*1|0)*$跨度>
  • 请不要添加“谢谢”作为答案。相反,请投票给您认为有帮助的答案。 - From Review
  • 您的答案不会向@KertOjasoo 的现有答案添加任何内容,就像您自己编写的那样。请不要添加基本上已经存在的答案。
【解决方案4】:

n+2n = 3n。因此,设置为 1 的 2 个相邻位表示 3 的倍数。如果相邻的 1 有奇数个,则不会是 3。

所以我建议这个正则表达式:

(0*(11)?)+

【讨论】:

  • 其实我错了。 2个相邻的就足够了,但不是必需的,例如9 = 1001。我的错。
猜你喜欢
  • 2013-02-26
  • 1970-01-01
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2016-04-01
  • 2011-08-02
相关资源
最近更新 更多