el-form-item如何限制只能输入数字_如何以计算机的方式去思考_ ...

el-form-item如何限制只能输入数字_如何以计算机的方式去思考_ ...

2023年7月3日发(作者:)

el-form-item如何限制只能输⼊数字_如何以计算机的⽅式去思考从上⼤学第⼀天开始接触编程,⽼师便给我们讲过各式各样的算法。从各种查找、排序,到递归、贪⼼等算法,⼤⼀的时候⼀直在和这些算法搏⽃。直到⼯作后,为了应付⾯试,仍不得不回过头去啃算法书或者去刷⼀些算法习题,才能够拾回⼀些上学时的记忆。为什么算法就这么难以记住呢?或者说,为何计算机的算法不能更直观⼀些呢?因为计算机的算法就是反⼈性的,从本质上来说,这是计算机的思维⽅式和⼈脑思维⽅式的区别⽽造成的。⼈脑思维的机制⾄今没有⼀个确定的理论,暂时认为是化学物质和电信号的作⽤。虽然没有科学的解释,但是我们每个⼈都有⼀颗⼤脑,我们每个⼈都可以感受到⾃⼰的思维⽅式。⽽计算机则是⼈类创造的,从设计之初它便不是以模拟⼈脑为⽬的,因此它有其独特的⼯作⽅式,只有理解了计算机的⼯作⽅式,才可以学会以它的⽅式去思考, 才可以写出最适合计算机运⾏的程序代码。在排序数组中寻找特定数字 —— ⼈脑 vs 计算机 round 1我们通过⼀个具体的例⼦,来说明⼈脑和计算机的思维⽅式不同,假设我们想要从⼀个已经排好序的数组中找出⼀个特定的数字。已知排序好的数组是1 2 3 5 7 13 34 67 90 127 308,我们希望找到是否13这个数在数组内。⼈脑是如何去完成任务的呢?⼈脑处理这样的问题⼏乎是“作弊”的,我们可以⼀⽬⼗⾏,我们在眼镜⼀扫视的情况下就发现了13,所以如果我问⾃⼰我是如何找到13的,我只能说我“看见”了。⽽计算机是如何来完成这个任务呢?最简单也是最笨的算法就是从数组开始⼀个⼀个的读⼊数组,我相信每个学习过编程基础的同学都可以写出类似下⾯的代码。boolean isNumInArray(int num, int[] array) { for (int i = 0; i < ; i++) { if (array[i] == num) { return true; } } return false;}计算机需要从数组的第⼀个元素开始,⼀个⼀个的去查当前的数组的元素,和13相⽐,看看是不是相等。为了找出13这个数,计算机要做6次循环操作,⽽⼈⼏乎是瞬间就看到了答案。为何计算机解决问题的⽅式这么“笨”呢?我们先得从计算机的⼯作原理说起。CPU的⼯作⽅式CPU作为计算机的最核⼼的部件,也是算法的主要运载体。CPU并不会像⼈⼀样思考,它只懂得⼀些基本的指令。每⼀个CPU都有其指令集,指令集是存储在CPU内部,对CPU运算进⾏指导和优化的硬程序。通俗⼀点说,指令集就是CPU的所有思维⽅式。⽐如常见的指令集中都会有ADD指令,这个指令可以将两个寄存器中的值相加,并将存储到另⼀个寄存器中;与此相对应的也会有SUB指令,⽤于将两个寄存器值相减。如果你去查阅各种CPU指令集的⼿册,会发现基本上都会包含基本的加减乘除指令,以及向内存中存、取数据的指令。⽽常见的CPU指令集,最多也就是⼏百条指令。也就是说CPU只会这⼏百个命令。⽽⼈脑相对于CPU,有强⼤的记忆和联想能⼒,⽐如你看到1+1,就想到2,看到红灯,就会想到停下来,看到门,就知道去开门把⼿,这些都是你不假思索可以⽴刻反映出来的东西。所以,CPU会的东西(指令)⽐⼈少多了,那CPU岂不是很笨?没错,CPU就是很笨,但是CPU的优点也是⼈脑所⽆法⽐拟的:1. 虽然CPU只会⼲简单的事情(⼏百种指令),但是它可以在固定的时间(指令执⾏时间)内保证正确的运算出正确的结果。⽽⼈脑不可能保证在固定的时间内⼀定产⽣“同样”的思维结果。2. 现代化的CPU⼯艺可以在⼀秒钟内执⾏百万次以上的指令,⽽⼈脑的思维速度则⽐不上,我们⼀个“念头”最短也需要零点零⼏秒的反应时间。综上所述,CPU是⼀个既笨⼜快的家伙。计算机存储计算机的常见存储有寄存器、⾼速缓存、内存、硬盘等。寄存器就相当于⼈脑中⽴刻可以想起来的东西,CPU所做的⼀切运算都是针对于在寄存器中的数据进⾏的。寄存器存储了计算机当前要做什么计算(指令寄存器),要计算的数据(数据寄存器),计算到哪⼀步了(段寄存器)等信息。⽆论是最早的有寄存器的CPU还是最新最强的的CPU,它们的寄存器数量最多也只有⼏⼗个(特殊情况有⼏百个),也就是说CPU同⼀时刻能够⽴刻使⽤过的信息也就是这⼏⼗个数字。内存则是计算机的主⼒存储设施,它可以存储运⾏中的程序的信息,内存相当于图书馆的书架,CPU需要⽤某⼀段内存中的数据是,需要通过LOAD指令,同时附上⼀个书架编号(内存地址),然后内存控制器可以将对应的地址的数据通过总线传输给CPU,CPU则将载⼊的结果放⼊寄存器中使⽤。内存存取的速度远⼩于寄存器,但是访问分布在内存各个区间的数据的速度基本是相等的。由于⼤部分时候CPU需要读取连续的⼀段内存来进⾏运算,因此通常CPU会有⾼速缓存将最近使⽤过的内存整块缓存起来,⽽使得CPU不必每执⾏⼀步就需要去读⼀次内存。⾼速缓存的速度介于寄存器和内存之间,但远⾼于内存。⾼速缓存的⼤⼩⼀般在⼏兆到⼗⼏兆之间。硬盘属于外部存储,⽼式的机械硬盘中会有⼀个可转的磁头,在读取磁盘⽂件的时候需要将磁头转到对应的位置,磁盘的速度远低于内存,并且如果磁盘的磁头如果停留在某个位置时,随机磁盘上不同位置的信息,会受到磁头运动的物理速度限制⽽出现速度不均等的情况。新式的固态硬盘采⽤了和内存相似的存储介质,在随机访问的性能上提升很⼤。所以,计算机有⼀颗只能记得⼀点点事情的⼩脑袋(寄存器),但是能够拥有相对较⼤的快速记忆(缓存),拥有远超过⼈类的知识储备(内存),并且还随⾝携带了巨⼤的移动图书馆(硬盘),所以从存储上来看,计算机像是⼀个有先天缺陷的⾬⼈(Rain Man)。所以,我们来分析⼀下round 1中为何计算机到底做了怎样的操作?⾸先我们看我们函数的定义boolean isNumInArray(int num, int[] array)

在调⽤函数的底层实现中,参数是被分配到两个寄存器中。isNumInArray这个函数,在被调⽤时,第⼀个参数num的值13会被载⼊到寄存器(r1), 的第⼆个参数array,传⼊CPU的时候就只是array在内存中的地址信息,被存储在另⼀个寄存器(r2)。⽽在第四⾏array[i] == num时,CPU需要做三件事才可以完成这⼯作:1. 通过ADD指令,根据array的地址(r2)和i(r4)的数字,计算需要读取的内存地址2. 通过LOAD指令将内存地址对应的数载⼊到寄存器(r3)3. 通过CMP指令⽐较num(r1)和r3的值,结果存储在结果存储器中⽽根据操作3的结果,如果结果不相等,则CPU需要将循环计数器i加上1存⼊寄存器r4,再次进⾏上⾯的计算。所不同的是,第⼆到第N次的步骤⼆会⽐第⼀次要快很多,因为整个数组的内容已经被⾼速缓存所捕获。所以,我们可以看出为何计算机在解决这个问题上显得如此愚笨:1. 计算机的输⼊收到限制。计算机⼀次只能读⼊单个值(有⾼速缓存的帮助这并不太糟糕),且在寄存器中放有限的⼏个值,⽽⼈类可以通过视觉等⼀次性读⼊多个值存储在脑海中。2. 计算机的指令有限制,只能⽀持基本的运算指令。⽽⼈脑可以有丰富的指令,⽐如直接通过⼀堆刚刚看到的数字中视觉模式匹配出13这个数字。在排序数组中寻找特定数字 —— ⼈脑 vs 计算机 round 2计算机在上⼀轮和⼈脑的PK中败下阵来,然⽽这并不是很公平,因为数组的数量只有短短的⼏个,⽽计算机可以存储的上限远不⽌于如此。于是我们开始第⼆次的⽐拼。 这次我们将输⼊扩⼤1 2 3 5 7 13 34 67 90 127 308 502 ... 2341245 ... (100万个查找的数变成了2341245。这次⼈脑和计算机的表现⼜如何呢?对于⼀个普通⼈,我们假设这100万个数字是打印在⼀本字典⾥的,那么他如何找出100万个有序数组中的某个数字呢?这时⼈类引以⾃豪的“⼀⽬⼗⾏”的能⼒已经微乎其微,当数字的位数增⼤时,且不说⼀眼⽐较⼀个数字是否和⽬标数字相同已经困难,即使真的有⼀⽬⼗⾏的本事,在100万这样的数字⾯前也是微乎其微。于是乎,我们⽼⽼实实的去从头到尾⽐较数字,⼀页⼀页的翻开,去看当前的页中有没有数字,没有的话就去翻下⼀页。这个思路是不是很熟悉?没错,这就是计算机的思维,和我们上⼀节中所描述的计算机编码⼏乎是⼀样的,除了⼈可以⼀眼多看⼏个数据外。然⽽,⼈类在⽐较⼤数是否相等的速度,以及翻字典的速度可远远⽐不上计算机去读完这100万个数的速度,同样是“笨鸟”,计算机每秒百万次的运算能⼒⼏乎可以在瞬间就完成这样的任务。也就是说,在⼤规模输⼊的情况下,⼈脑的思维⽅式“退化”成和计算机近似,但是被计算机压倒性的性能优势给击败。在排序数组中寻找特定数字 —— ⼈脑 vs 计算机 round 3在第⼆轮中,⼈脑败给了计算机,但这样的⽐拼⽆疑于两只笨鸟⽐谁更快。有没有聪明⼀些的⽅法呢?没错,我们学过⼆分查找(Binary Search)的算法可以派上⽤场了。步骤⼀:有这么有⼀本打印了100万个数字的字典摆在我们的⾯前,我们不知道要找的数字会在哪⾥,那么我们先折半打开字典(不⽤那么精确也没关系),看当前页的第⼀个数字和最后⼀个数字,我们要找的数字是否在这个范围内,如果在那么我们可以继续在当前页找这个数字。步骤⼆:如果当前页的第⼀个数字还是⽐我们要找的数字⼤,那么我们可以将字典的后半部分撕了(因为我们要找的数字不可能在后半部分了),继续上⾯的步骤。步骤三:如果当前页的最后⼀个数字⽐我们要找的数字⼩,那么我们可以将字典的前半部分撕了(理由同上),继续步骤⼀。这样我们会讲这本字典越撕越薄,最坏的情况下我们会撕到最后⼀页,这⼀页要么有这个数字,要么没有这个数字,但是我们保证按照上⾯的步骤进⾏我们不会错过任何可能含有这个数字⼀页。这个逻辑和计算机算法中的⼆分查找原理是⼀样的,我们来看看实际的算法代码是如何实现的boolean isNumInArray(int num, int[] array, int start, int end) { if(num < arr[start] || key > arr[end] || start > end){ return false; } int middle = (start + end) / 2找到我们可以看出,和⼈类的思维⽅式⽐,计算机不会翻“⼀页”,它只会翻看⼀个数字,但是其他的思维⽅式是⼀模⼀样的。利⽤这样的算法,⼈类虽然从结果上还是⽐计算机要慢,但是双⽅都找到了最适合的⽅法,达到⾃我效率的最⼤提升。在排序数组中寻找特定数字 —— 更多的思考那么我们回过头来看,为什么我要假设这100万数字打印在字典上呢?因为字典和计算机内存的模型很像。计算机可以通过内存地址来直接访问内存,这⼀点和通过字典的页码来翻到某⼀页,这⼀点是近似的。在计算机编码中我们可以知道数组的长度,⽽通过折半的⽅法找到中间的数,字典有厚度,我们可以通过厚度减半来找到中间的页码,这⼀点也是相似的。试想⼀样,如果100万的数字不是打印在字典,⽽是印在⼀条公路上,我们是否还可以⽤上⼀节的算法来⼈⾁⼆分查找?答案是不可以,因为跑到公路的⼀半会消耗你很多的体⼒,如果采⽤⼆分法查找⽐起round 1中的最笨办法只会让你耗费更多的体⼒。因为公路这⼀存储的概念,对应的便不是内存的模型,⽽是磁带(Tape)的模型,那么对于这样的模型,我相信不论是⼈或者是计算机, 都需要调整算法,来达到最⾼的效率。总结通过以上的例⼦,我们可以看到,计算机的算法反⼈性,是因为计算机不是⼀个“正常⼈”,它有⾃⼰的缺陷,也有⾃⼰的长处。很多时候我们觉的算法不直观,不是因为我们的思维能⼒⽐计算机差,⽽恰恰是因为作为⼈类我们同时接触的信息太多,所会的东西也太多⽽阻塞了我们的思维。那么这种时候,不妨将⾃⼰“堕落”成⼀台“⿏⽬⼨光”和“所知甚少”的计算机,这时可能会有更清晰的思路。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688329695a121164.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信