你可能永远都搞不懂了图灵机了!

程序员都知道图灵机,但是却不一定能搞懂它,不一定理解它为什么这么厉害。

原因就是:图灵机太简单了,太数学了, 太抽象了。 

1

我刚上大学的时候,有个社团叫“图灵学社”,当时我还纳闷,图灵是谁?

我就跑到图书馆去查书:哇,图灵原来是我们的祖师爷啊,我们全靠他赏饭吃。 

等等,这图灵机是什么玩意儿,一条纸带,一个读写头,一个控制器, 这也太简单了吧。

现在的电脑有漂亮的界面,丰富的操作,有视频,图片,声音。 

编程中有虚拟机,各种框架,并发模型,设计模式,面向对象,泛型,函数式,闭包。

这么复杂的东西,怎么可能归结到如此简单的图灵机中?这不是痴心妄想吗?

3

这还真不是痴心妄想。因为计算机使用的二进制数字可以表示一切!

先说图像

图像有两种存储方式,一种是位图,一种是矢量图

位图相当于把整个图像分解成一个个小的像素,每个像素都有颜色,这样就可以用二进制数字表达了。

就像下面这张笑脸图:

(可以看出图像放大以后就出现锯齿了。)

而矢量图相当于记录下了一个图像的几何信息。

比如一个圆,只要知道

1. 圆心

2. 半径

3. 绘制时的线型和颜色

就可以把他复原了, 很明显,这些数据也可以用二进制表示。

视频则是一帧帧的图像组成,既然图像可以用二进制表示,那视频肯定也没问题。

声音也是类似的,本来是连续的,但是电脑会对他进行采样(比如每秒采样44100次),变成离散的,就可以用二进制表达,存放到电脑中了。

(音频信号也出现锯齿了,因为数据是离散的,不是连续的了,不过只要采样频率高,人的耳朵分辨不出来)

所以,视频,图像,文本,声音都可以用二进制来表达,然后写程序对他们进行处理就行了。 

至于各种语言编写的程序,无论是系统级的操作系统,还是应用层的Web网站, 最终都要归结到赋值,顺序,循环,分支这些最基本的结构。

如果你不相信,可以看看我之前写过几篇的文章:

编程语言的巅峰

C语言哭了,过年回家,只有我没有对象

这世界上根本没什么面向对象

所以只要图灵机能表达这些最基本的结构,一切问题就都解决了。 

3

本文的重点终于来了, 图灵机如何去表达这些基本的结构呢?

进入烧脑环节,强烈建议找一块儿安静的时间来阅读。  

其实做为一个程序员,多用脑子是好事,不要一遇到难点儿的东西就逃了,那样怎么会进步和成长呢?

我们先从一个极其简单的编程语言来热身, 这个语言只有三条指令

1. 递增   

incr(X)

2. 递减

decr(X)

3. 循环

while(X){

    decr(X)

    //做一些事情

}

别小看这三条指令,从它们出发,可以组合出很多新的指令,可以把这些指令称为宏。 

这些宏一旦建立,可以再次被组合使用

第一个宏:   把一个变量X的值清0,记做 X <--0

while(X){

    decr(X)

}

第二个宏:  给一个变量赋值,记做 X <-- n

X <-- 0  //复用第一个宏

incr(X)

incr(X)

incr(X)

.....

incr(X)   //重复n次,不要嫌啰嗦,计算机最适合,最擅长干这种重复的事情

第三个宏:把X的赋值给Y ,记做 Y <--X

Y <--0    //利用第二个宏

while(X){

    decr(X)

    incr(Y)

}

第四个宏:实现if 语句  ,记做 if X then A

//注意,X的值只能是0或者1

while(X){

    decr(X)

    A 

}

实际上,只要你愿意,还可以组合出各种各样的新指令

Y <--- Y + X  

Y <--- Y * X

......

只不过需要花费更多的指令罢了。 

也就是说这个简单的语言能实现上一节所说的赋值,顺序,循环,分支等基本结构。 

那如果图灵机和这个简单语言也是等价的,那图灵机肯定能实现赋值,顺序,循环,分支了,对吧? 

4

接下来我们把目光转向一个“寒酸”的图灵机, 让它来实现decr(X), incr(X), while(X)

这个图灵机的磁带上只有空白(b)和字符 (1)两种选择

两个空白之间有多少个1就表示数字是多少,例如有4个1表示4, 10个1表示 10

下图就表示数字7

就是这么简单粗暴!

磁带上的读写头总是指向磁带上的一个符号(当前符号),读写完成以后,它可以左移,右移或者呆那儿不动, 这依赖于控制器中的指令是什么样子的。

最重要的是那个控制器,相当于现代的CPU了,它是一个有限状态的自动机,可以在有限的状态中根据输入转入另外一个状态。 

我们现在试试用这个“寒酸”的图灵机来实现incr(X) :对X加 1 。 

为了方便说明,假设X为7, 读写头初始状态位于最左端的空白处

是不是很简单? 

当然,这里可以用有限状态机来描述,为了降低理解负担, 我用大白话来说了。

想实现decr (X) ,就更简单了, 我们把刚才的X=8,减去1

首先让读写头右移,遇到1,把它变成b ,停止就行。

循环要稍微复杂一点儿,仔细看好了。 

假设X = 3,循环是这样的

while(X){

     循环体

}

三种基本的运算实现了,现在我们可以说:

简单图灵机 <--> 简单语言 <-->  复杂的语言

好了,证明完毕!不知道你晕了没有。

其实这根本不是证明,就是希望大家能感受下图灵这么简单的机器,也有着强悍的能力,就是实现起来比较费劲罢了。 

后记:本文的简单语言和图灵机的例子来源于佛罗赞的《计算机科学导论》,这本书相当不错,推荐!

码农翻身3年精华文章(必读!)

漫画丨让你专心干技术,没让你干到35岁啊…

漫画 | Linux之父:我财务自由以后,失眠了

漫画:打死我也不搞负载均衡了

漫画:兄弟,今晚又得熬个通宵了!

架构师劝退指南

程序员的宿命

宇宙第一IDE到底是谁?

HTTP Server :一个差生的逆袭

如何降低程序员的工资?

程序员,你得选准跑路的时间!

Javascript: 一个屌丝的逆袭

我是一个线程

TCP/IP之大明邮差

一个故事讲完Https

CPU 阿甘

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值