CS自修室第三期:认识算法,学会用最高效最正确的方法解决问题,才是学习编程的首要原则

- 1 -

2021年03月07日。

周日。

这是奶爸进击之旅——CS自修室的第三期更新。

- 2 -

上会书说道……

啊呸,不对,上期总结介绍到ASCII系统的局限性,限制了其在空间发展的维度,基本上只能表示英语语言的字符,对于其他语言的字符的表示,则远远达不到要求。

那么,如今,到底应用的是何种编排系统,才使得在全球范围内各语言都可以互联通用呢?

那就是Unicode系统

它不仅支持英语,还支持所有人类语言,相对于ASCII以8bits来表示,Unicode系统可以做到以8bits、16bits、24bits甚至32bits来表示字符了。

要弄清楚计算机的原理,必须要明白一个非常重要的原则,就是计算机所显示的任何字符,其实都是通过零和一构成的。

如我们熟知的emoji表情,虽然它在我们眼里是图形的样貌,但实际上,在计算机中,它仍是以零和一组成的位作为表示。

比如你接收到一个‘’的表情,实际上,你只是收到看起来像是一个这样的位模式——‘000000011111011000000010’。

到现在,已经知道计算机如何代表一个字符或一个图形表情了,但现实世界并非处于黑白的状态,计算机也是如此。

所以,计算机是如何代表一种颜色呢?或者说,一种颜色如何在计算机中表示出来呢?

同样的道理,也是给颜色编排一个位模式的系统,让其代表各种颜色。

即便不知道这个原理,想必在平时也都用过RGB色彩模式吧。

R代表红色(red)、G代表绿色(green)、B代表蓝色(blue)。

计算机上显示的所有颜色,都是由这三种颜色相互叠加、混合而得到的,它几乎能呈现人类视力所能感知的所有颜色。

然后这些代表颜色的位模式又形成像素点(3bytes或24bits组成一个像素点),成千上万的像素点组成一个图形,因此,我们又能在计算机上看到图片、照片等像素图形。

如果你把一张照片放大到最大的状态,也就能看到这些像素格,像拼图一样一个一个拼接起来,最终形成一张色彩丰富的图片。

那么,计算机是如何表示视频的呢?

其实也很简单,只要每次改变一点像素格,然后将这些画面连续地动起来,就成为了视频。

也就是说,在某种意义上,视频只是一堆图像以非常迅速的动态在屏幕上闪动所形成的动态画面。

就像你童年时代在书角上画各种小人图,然后快速翻页形成的动态漫画一样,这就是视频形成的原理。

同理,我们同样也可以使用数字来代表歌曲中的音符以及用数字代表音符间的持续时间等,从而让计算机实现对音乐的表示。

所以,计算机上如此多的文件,如JPG、MP3、GIF、word文件等等,所有这些不同扩展名的文件或文件格式,全都是经过普遍认可约定——如何在文件中存储零和一的模式。

这样,当这些文件被加载到计算机中进行显示或解析时,计算机能清楚的知道这些模式代表的是什么。

虽然图片、音乐、视频的表示方式有所不同,但目前为止,所有这些已知的文件,全都是以零和一模式组成的。

- 3 -

上期总结说道:

计算机科学是一个解决问题的方法,还展示了一个输入输出的图形解释如下:

目前,已经得知计算机是如何表示信息,也就知道如何表示问题的输入,也预期着得到解决问题的方案输出。

所以,眼下仍存在问题就是,白色框架内,是如何进行输入的(无论是声音、图片还是数字等任何形式),并将其转化为实际的解决方案。

而白色框架内,以专业术语来描述,它就是人们常说的算法(algorithms)

何为算法?

算法就是以分步解决问题的一种方法,它甚至不必专门指代计算机算法。我们人类只要遵循别人的指令同样也可以执行算法。

类似于食谱,你在学习某种菜式的时候,根据食谱一步一步制作,其实就是在逐步地执行算法。

但是与食谱不同的是,计算机所执行的算法必须是无歧义、精确、完全正确的。

所以,在对计算机进行编程时,也就是在翻译算法,将逐步的算法,逐一翻译为计算机可以识别的某种语言,并确保计算机不会误解你输入的信息。

手机里‘通讯录’的程序大家都知道,它存储着你亲朋好友的联系方式,通常以字母顺序为排序。

在电子通讯录问世之前,人类还是用着纸质版的电话簿。

同样,里面存储着一堆的电话号码,并以字母顺序排序。

如果需要在纸质电话簿里寻找一个人的号码,最笨拙的方法就是一页一页的翻下去,直到找到你想要找的号码。

但,即便这种算法是正确的,可它相当的缓慢,如果一本2000页的电话簿,里面有数十万条号码,你要翻到什么时候才能找到呢?

答案可想而知,即便你两三页跳跃着翻阅,比原来的速度快了一倍,也同样会耗费非常久的时间,甚至还有可能跳过你需要找的那一个号码。

所以,计算机算法还有一个重要原则,它不仅仅只考虑它的正确性,还要考虑它的效率。

正确性和高效率是评价一个算法设计得好坏的标准。

当然,现实中,谁也不会用这么笨的方法去搜索一个号码。

既然电话簿是按照字母顺序排序的,比较明智的方法通常都是随手翻开,看一下到底是在哪个字母段,在观察前后部分。如果是在将要寻找的字母段之后的字母,我们就可以放弃后面的部分,在前半部分继续寻找。

再用同样的方法,翻开一半,看字母段所在位置,不断地缩小搜索范围,最终精确到某一页,找到该号码。

这样的算法肯定比一页一页翻查快速得多,如三种算法的函数对比图可见:

如图可见,即便第二种两页两页翻查的速度比第一种快了一倍,却仍需要耗费很多的时间,更严重的问题是,当电话簿越来越厚,则需要耗费的时间则越来越长。

而且第二种算法含有跳过结果的风险错误,这种错误则称之为Bug,需要施加条件加以修复才行。

只有第三种方法,无论这个电话簿变得多厚,它所耗费的时间都不会增加太多,因为它把问题不断分解,把复杂的问题简单化了,这种算法又正确又高效,才是值得推崇的好算法。

- 4 -

当然,算法需要将其转化为代码,使计算机理解,才能让计算机执行。

在了解代码之前,我们先通过书面语言翻译一下该算法,这种书面表达的代码被称之为伪代码(pseudocode)。

不过,翻译伪代码时,仍要保证它的准确性。

以下为前文提到的第三种算法的伪代码:

1、拿起电话簿;
2、从中间将电话簿打开;
3、查看该页;
4、如果待寻人的号码在该页上;
5、    打给她/他;
6、如果待寻人的号码在该页之前;
7、    从前半部的中间将电话簿打开;
8、    回到第三步;
9、如果待寻人的号码在该页之后;
10、  从后半部的中间将电话簿打开;
11、  回到第三步;
12、如果待寻人的号码不在电话簿上;
13、  关闭电话簿(退出);

当然,并不是所有程序都会将所有可能出现的结果都设想出来,之所以计算机或程序会出现死机等问题,就是因为编写该程序的程序员并没有把所有可能出现的问题都编写进程序中。

另外,我个人觉得直接看英文的伪代码会更好理解一点,所以也放上英文版。

这些黄色高亮部分,在编程中,实际上称之为functions,functions实际上就是动作,是命令计算机执行的某项操作的声明。

上图高亮部分则是conditions(表示条件),表示是否执行该操作还是其他操作。

所以要判断执行哪一个操作,就需要用到条件判断的表达式,它就是布尔表达式(Boolean expressions),布尔表达式的答案很简单,只有True 或者 False,实际上就是1或者0。

下图高亮部分代表布尔表达式。

最后,下图高亮部分则是loops(表示循环),让你可以重复地执行某一项操作,让你不必编写几百行代码去执行同样的操作。

所有这些functions、conditions、boolean expressions、loops等等共同组成了实际的代码。

不过,如何将这些伪代码转化成实际的代码,这又是一个新的课题,本期总结先到此为止,我们下期继续。

01010100 01101000 01100001 01101110 01101011 01111001 01101111 01110101 00100001

——我就是可可奶爸,一个平平无奇的全职奶爸

我只是一个平平无奇的全职奶爸,不敢指导你什么,只想和你一起共同成长。

关注公号:Irene_Daddy 【进击的可可奶爸】

本号的更新内容:

周一,马拉松幻视:以马拉松为目标,每周跑步总结。

周三,英语屋:总结学习时收获的英语口语表达,以及一些英文的学习方法。

周五:向往的N2:以考取日语N2为目标,每周学习总结。

周日:CS自修室:自学CS的每周总结。

还有不定时的更新奶爸的日常:读书、观影的一些碎碎念,偶尔的秀恩爱撒狗粮,不时的亲子活动等……

你可能感兴趣的:(CS自修室第三期:认识算法,学会用最高效最正确的方法解决问题,才是学习编程的首要原则)