算法,即解决问题的方法。同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的。 就比如要拧一个螺母,使用扳手还是钳子是有区别的,虽然使用钳子也能拧螺母,但是没有扳手好用。
“条条大路通罗马”,解决问题的算法有多种,这就需要判断哪个算法“更好”
算法 / 程序很多人误以为程序就是算法,其实不然,算法是解决某个问题的想法、思路,而程序是在心中有算法的前提下编写出来的可以运行的代码。
例如,要解决依次输出一维数组中的数据元素的值的问题,首先想到的是使用循环结构( for 或者 while ),在有这个算法的基础上,开始编写程序。
算法相当于是程序的雏形,当解决问题时首先心中要有解决问题的算法,围绕算法编写出程序代码。
有算法不一定能解决问题对于一个问题,想出解决的算法,不一定就能解决这个问题。
例如拧螺母,扳手相对于钳子来说更好使(选择算法的过程),但是在拧的过程(编写程序的过程)中发现螺母生锈拧不动,这时就需要另想办法。为了避免这种情况的发生,要充分全面地思考问题,尽可能地考虑到所有地可能情况,慎重选择算法。
“好”算法的标准对于一个问题的算法来说,之所以称之为算法,首先它必须能够解决这个问题,称为准确性。其次,通过这个算法编写的程序要求在任何情况下不能崩溃,称为健壮性。
如果准确性和健壮性都满足,接下来还要考虑最重要的一点:通过算法编写的程序,运行的效率怎么样。
运行效率体现在两方面:
- 算法的运行时间(称为“时间复杂度”)
- 运行算法所需的内存空间大小(称为“空间复杂度”)
好算法的标准就是:在符合算法本身的要求的基础上,使用算法编写的程序运行的时间短,运行过程中占用的内存空间少,就可以称这个算法是“好算法”。
调查表明,人们对于软件或者 APP 的运行效率有极高的要求,例如对于网页打开的忍耐极限是 6 秒甚至更短,如果你设计的网页打开的时间超过 6 秒,多数人会在 4 秒甚至 3 秒的时候毫不犹豫地关掉而去浏览其他网页。在这个大背景下,一个好的“算法”更注重的是时间复杂度,而空间复杂度只要在一个合理的范围内就可以了,Google就是这么做的。
时间复杂度计算一个算法的时间复杂度,不可能把所有的算法都编写出实际的程序出来让计算机跑,这样会做很多无用功,效率太低。实际采用的方法是估算算法的时间复杂度。
程序由三种结构构成:顺序结构、分支结构和循环结构。顺序结构和分支结构中的每段代码只运行一次;循环结构中的代码的运行时间要看循环的次数。
由于是估算算法的时间复杂度,相比而言,循环结构对算法的执行时间影响更大。所以,算法的时间复杂度,主要看算法中使用到的循环结构中代码循环的次数(称为“频度”)。次数越少,算法的时间复杂度越低。
例如:
// A
++x; s=0;
// B
for (int i=1; i
关注
打赏
- uni-app - 随机数生成器,随机生成指定区间的整数或小数(支持指定小数点的位数)
- uni-app - 节流与防抖(按钮节流、输入框防抖解决方案)
- 微信小程序 - 页面触底 onReachBottom() 懒加载自动计算分页、检查是否已经请求完全部数据、自动请求接口合并数据(高效自动判断分页懒加载是否继续请求接口数据,超详细触底请求后端示例教程)
- JavaScript - 简单快速,根据条件剔除删除对象中某个字段键值(key / value)
- 微信小程序 - wx.navigateTo 跳转的路径携带 query 等参数,直接被忽略截断了(只剩网页域名后面的参数都没了),导致无法顺利传递给 web-view 组件(解决方案)
- JavaScript - 判断当前网页是否在微信内置浏览器中运行(最靠谱的方案,检查是否在微信浏览器中打开网站或页面)
- JavaScript - 纯 JS 实现让浏览器滚动条回到顶部(3种解决方案)
- uni-app - 根据后端返回的唯一 ID / code,生成 “唯一“ 的推荐码、邀请码、订单号、加密路由、一串英文+数字长字符等 (支持反序列化原 ID 解码,逆向得出 ID 二者互转)
- Vue Nuxt.js - 根据后端返回的唯一 ID / code,生成 “唯一“ 的推荐码、邀请码、订单号、加密路由、一串英文+数字长字符等 (支持反序列化原 ID 解码,逆向得出 ID 二者互转)
- JavaScript - 根据后端返回的唯一 ID / code,生成 “唯一“ 的推荐码、邀请码、订单号、加密路由、一串英文+数字长字符等 (支持反序列化原 ID 解码,逆向得出 ID 二者互转)