我们之前已经见过了正则表达式的一些很特殊的用法。这里我们再来看一个:用正则表达式判断数的整除性。例如,下面这个表达式可以匹配01串S当且仅当S是一个可以被3整除的二进制数。

^1((10*1)|(01*0))*10*$

如果你不信的话,不妨把下面这段代码粘贴进浏览器的地址栏,然后回车运行一下:

javascript:alert(/^1((10*1)|(01*0))*10*$/.test("1000000100"))

被test的是516的二进制表达。516可以被3整除,因此程序返回true。你可以自己把1000000100换成其它的二进制数试试。

但是呢,从这个正则表达式里我们竟看不出任何端倪。奇怪了,为什么这个正则表达式可以用于判断整除性?能被3整除的二进制数究竟有何规律?

其实,能被3整除的二进制数并没有什么明显的规律。这个正则表达式的求法可以说是相当暴力的。这一切的谜底很简单——判断一个数的整除性能轻易地用有限状态自动机实现,而有限状态自动机又可以翻译成正则表达式。

注意到,一个二进制数后面加一个“0”相当于该数乘以2,一个二进制数后面加一个“1”相当于该数乘2加1。设定三个状态,分别叫做0、1和2,它们表示当前的数除以3所得的余数。如果对于某个i和j,有i*2≡j (mod 3),就加一条路径i→j,路径上标一个字符“0”;如果i*2+1≡j (mod 3),则在路径i→j上标记“1”。状态0既是我们的初始状态,也是我们的最终状态。我们的自动机就做好了。现在,假如二进制数10010走进来了。从状态0出发,机器首先读到一个“1”,于是当前位置挪到状态1,表明目前该数模3余1;然后,系统读了一个“0”,我们紧跟着走到状态2,表明二进制数“10”被3除余2;下一步,我们回到状态1,表明“100”除以3余1;再往后,我们得知“1001”能被3整除。最后呢,我们读到一个0,“1001”的两倍当然还是能被3整除,我们依旧停留在原位。我们得到结论:二进制数10010能被3整除。

有限状态自动机是可以转化为正则表达式的。上面的这个自动机转化起来非常容易。我们可以先试着用自然语言叙述一下。首先,每个二进制数第一位必然为“1”。到达状态1后,我们可以随意地、任意多次地在状态1周围绕圈圈,最终回到状态1。临近末尾,我们再读到一个“1”返回状态0,这之后随便读多少个“0”都可以了。现在问题分解为:我们又如何用正则表达式表述“从状态1出发随意地走最终回到状态1”呢?在本例中,这是很好描述的:它可以是字符串“1000..001”和“0111..110”的任意组合。把这些东西用正则表达式写出来,就是我们刚才那个神秘的式子:1((10*1)|(01*0))*10* 。

从原理上说,我们可以这种方法求出任意进制下用于任意数的整除性判断的正则表达式。只不过,它们所对应的自动机都更加复杂,从而得出一长串令人眼花缭乱的表达式。本文开头我把1((10*1)|(01*0))*10*的来源作为一个有趣的问题提出来,因为这个式子恰好不长,让人很难想到这背后藏有一个普适的暴力算法。

java 正则判断二进制_用正则表达式判断一个二进制数是否能被3整除相关推荐

  1. java判断手机号_java使用正则表达式判断手机号的方法示例

    本文实例讲述了java使用正则表达式判断手机号的方法.分享给大家供大家参考,具体如下: 要更加准确的匹配手机号码只匹配11位数字是不够的,比如说就没有以144开始的号码段, 故先要整清楚现在已经开放了 ...

  2. oracle正则判断数字开头,oracle 正则表达式判断是否数字

    oracle 正则表达式判断是否数字 发布时间:2018-12-13 10:35, 浏览次数:375 , 标签: oracle 正则表达式 ORACLE中的支持正则表达式的函数主要有下面四个: 1,R ...

  3. java 正则 单个字符_正则表达式教程之匹配单个字符详解

    本文实例讲述了正则表达式教程之匹配单个字符.分享给大家供大家参考,具体如下: 注:在所有例子中正则表达式匹配结果包含在源文本中的[和]之间,有的例子会使用Java来实现,如果是java本身正则表达式的 ...

  4. java 正则提取邮箱_如何用正则表达式提取一个网站里面的所有邮箱地址?

    展开全部 用正则表达式提取一个网站里面的所有邮箱地址e68a8462616964757a686964616f31333337616565 import java.io.BufferedReader; ...

  5. 用正则表达式判断一个二进制数是否能被3整除

    我们之前已经见过了正则表达式的一些很特殊的用法.这里我们再来看一个:用正则表达式判断数的整除性.例如,下面这个表达式可以匹配01串S当且仅当S是一个可以被3整除的二进制数. ^1((10*1)|(01 ...

  6. ios 判断数字开头_iOS 正则表达式判断纯数字及匹配11位手机号码的方法

    第一种使用正则表达式 判断 //是否是纯数字 + (BOOL)isNumText:(NSString *)str{ NSString * regex = @"(/^[0-9]*$/)&quo ...

  7. java正则开头结尾_以m开头以d结尾的正则表达式-正则表达式以什么开头-正则表达式不以0开头...

    正则表达式:数字开头中间字母结尾数字 如果你的结尾数字是多个也可以的话,你就要再加上一个+号,另外,中间的字母允许大写幺?允许的话要再加上A-Z,所以你可以改这样试试: "^[0-9]+[a ...

  8. java正则匹配汉字_正则表达式匹配中文汉字

    文章告诉你如何利用php教程 正则表达式匹配中文汉字哦,下面我们主要讲利用preg_match mb_eregi来验证汉字,并且正则过程出现问题的解决方法. preg_match("/[a- ...

  9. java正则任意字符_正则表达式匹配任意字符(包括换行符)的写法

    今天在Java中想使用正则表达式来获取一段文本中的任意字符.于是很随意得就写出如下匹配规则: (.*) 结果运行之后才发现,无法获得换行之后的文本.于是查了一下手册,才发现正则表达式中,". ...

最新文章

  1. mysql表创建在哪_mysql创建表命令是哪句
  2. 自己写的一个抢票加速的Python小程序源码分享-----纯属娱乐
  3. jQuery幻灯片skitter-slider插件学习总结
  4. Android数据保存之SharedPreference
  5. 工业用微型计算机笔记(1)-进制转换
  6. 详解GAN的谱归一化(Spectral Normalization)
  7. Bless You Autocorrect!
  8. ssh主机之间建立互信 --免密码
  9. 十万个为什么儿童版_把中国科技传播至阿语地区,少儿社《十万个为什么》阿拉伯文版亮相童书展...
  10. 什么时候应该避免写代码注释?
  11. CVPR 2019 论文大盘点—文本图像相关篇
  12. H5实例 移动端页面练习
  13. 存储区域网络(Storage Area Network,简称SAN)
  14. 暖风熏的游人醉 直把杭州作汴州 题临安邸--林升
  15. unity3D-learning:UI背包系统
  16. 酒桌小游戏喝酒小程序
  17. 微信小程序常见面试题与总结
  18. Hash索引和BTree索引区别
  19. c语言怎么做翻译软件,使用有道翻译API做翻译(c语言实现)
  20. ArcGIS分级显示

热门文章

  1. asp.net处理机制管道事件
  2. Windows 下mysqldump备份1045错误解决办法
  3. npm audit fix
  4. Python序列之字符串
  5. Controller层返回字符串
  6. 通过编写串口助手工具学习MFC过程——(三)Unicode字符集的宽字符和多字节字符转换...
  7. JQuery提供了丰富的选择器
  8. java面试题及答案 JAVA相关基础知识
  9. Python sysos模块
  10. 二叉搜索树与双向链表的转换