我们之前已经见过了正则表达式的一些很特殊的用法。这里我们再来看一个:用正则表达式判断数的整除性。例如,下面这个表达式可以匹配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*的来源作为一个有趣的问题提出来,因为这个式子恰好不长,让人很难想到这背后藏有一个普适的暴力算法。

转载于:https://www.cnblogs.com/hdk1993/p/4823711.html

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

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

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

  2. 判断一个大整数能否被11整除

    设计算法,判断一个大整数能否被11整除.可以通过以下方法:将该数的十进制表示从右端开始,每两位一组构成一个整数,然后将这些数相加,判断其和能否被11整除.例如,将562843748分割成5,62,84 ...

  3. 在Java中用正则表达式判断一个字符串是否是数字的方法

    package chengyujia;import java.util.regex.Pattern;public class NumberUtil {/*** 判断一个字符串是否是数字.* * @pa ...

  4. java用正则表达式判断一个字符串是否是车牌号

    public boolean checkCarNumber(String content) {String pattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏 ...

  5. 判断一个整数是否能被7整除或者数中含7

    #include <iostream> #include <algorithm> #include <string> #include <sstream> ...

  6. java正则判断日期格式_Java中用正则表达式判断日期格式是否正确

    1.Java中用正则表达式判断日期格式是否正确 DateType.java: /** * @Title:DateType.java * @Package:com.you.dao * @Descript ...

  7. python整数二进制有多少个1_几种统计一个二进制数内有几个1的方法

    几种统计一个二进制数内有几个1的方法 方法一: int f1(int temp) { int num = 0; while(temp) { int t = temp%2; if(t == 1 || t ...

  8. JavaScript —— 如何判断一个非数字输入

    在页面里,如何用JS去判断一个用户输入是不是一个数字. 你是不是首先想到了正则表达式? JS里有个现成的函数,isNaN(x) isNaN(x) 函数可用于判断其参数是否是 NaN(Not a Num ...

  9. 如何判断一个字符串在JavaScript中是否包含某个字符?

    本文翻译自:How to tell if a string contains a certain character in JavaScript? I have a page with a textb ...

最新文章

  1. [JSOI2008]魔兽地图
  2. java helloworld代码_java学习应用篇|逃不掉的HelloWorld
  3. VTK:PolyData之ContourToImageData
  4. python中while语句是_如何在Python中使用while语句[适合初学者]
  5. NodeJs express自定义中间件
  6. javassist组件分享利用javassist动态创建一个类
  7. dns缓存时间 linux,如何在Linux服务器上刷新DNS缓存
  8. Python基础语法回顾
  9. 计算机更改开机密码快捷方法,win7怎么修改开机密码(最快) win7修改开机密码最便捷的方法...
  10. 读书笔记--认知突围
  11. 支付宝支付-当面付和App支付
  12. 如何用python找文献_如何高效查找文献、紧跟研究领域热点和前沿?
  13. Linux下访问默认80端口 映射到8080端口
  14. android 微信分身开发,【技巧】2021安卓手机微信分身方法
  15. 没有一只蟹能活着爬出上海
  16. adb发送什么命令能在手机屏幕弹窗显示_常用命令之adb指令
  17. python客户端开发自行车租赁系统_Python数据分析,自行车租赁数据分析,租赁情况怎么样?...
  18. (C++)Windows自动锁屏程序
  19. 张娅老师:人力资源管理不规范中小企业怎么破解
  20. 数据结构(廿六) -- C语言版 -- 图 - 图的遍历 -- 邻接表 - 深度/广度优先遍历/搜索(DFS、BFS)

热门文章

  1. 【发现】ASP.NET DEVELOPMENT SERVER 未能开始侦听端口xxxxx以一种访问权限不允许的方式做了一个访问套接字的尝试——解决方法...
  2. Excel财务报表制作技巧与综合案例操作
  3. Echart图表X轴为时间轴的解释
  4. 紫书 习题7-14 UVa 307(暴搜+剪枝)
  5. MVC 中使用bootstrap-select 基础使用方法
  6. 团队-象棋游戏-开发文档
  7. Sql 某一字段统计
  8. Python 爬虫修养-处理动态网页
  9. Javascript Java C++系列
  10. ⒈Altiris cms 7.0 安装前准备工作