前端工程师算法(一)
算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指定,算法代表着用系统的方法描述解决问题的策略机制。这个解释来源于百度,对于入门来说这个解释等于白说了,你的一脸懵逼我懂,大神略过。
- 说人话
- 算法
- 你需要了解的算法是什么?
开始了解算法就应该对程序有一些认识和理解了,其实我们所有的程序可以理解为算法加数据结构。撇开数据结构不谈,我们日常写的代码如if-else、for(...)等就是算法。在数学里加减乘除是算法,方程公式,几何公式,乃至高数也都是算法,而我们的if-else、for(...)就相当于数学中的加减乘除这种级别的算法,当然在程序里也有加减乘除,同样也是算法。
但是我们日常所表达的算法和算法通常的说法有一些区别,我们日常表达的算法基本上都是特指一些特殊的算法,这些特殊的算法就相当于数学中的高数级别(不是指难度)。这些算法的特殊性并非其难度,而是具备通用性、高效(空间和时间)、解决特定问题的程序。
前端常用算法之数组查重算法
在前端编程中查重是比较常见的应用,以数组查重为例,通常的思路是通过嵌套循环,让每个值与其他每个值进行逐个对比。思路有了,我们就来实现以下:
var arr = [8,4,79,38,2,67,4,19,8,13,47,68,37,13,48,2]; var cont = 0;//记录比较次数 for(var i = 0; i < arr.length; i++){for(var j = 0; j < arr.length; j++){if(arr[i] == arr[j] && i != j){//'i != j'-->排除与自己比较 console.log(arr[i]);}cont ++;//累计 } } console.log(cont);//256
这个查重算法可以说基本就实现了,因为解决了特定问题:找到重复的元素。但是这个算法并不是我们真正需要的算法,因为这样对比出现了很多重复,浪费很多计算资源和时间,所以这个算法需要改进。
改进的目的就是消除重复对比,从数组的有序性我们可以知道,每一次内部循环不需要从头开始对比,因为前面已经对比过了,所以改进代码如下:
for(var i = 0; i < arr.length; i++){for(var j = i + 1; j < arr.length ; j++){//i+1表示自身和自身之前的元素都不需要比较了if(arr[i] == arr[j]){console.log(arr[i]);}cont ++;//累计 } } console.log(cont);//120
这样改进后的查重效率可以从对比次数看到,减少了一半多,也就说明了改进后的查重算法效率提高了一倍多。在算法中,不存在对错的概念,而是在保证实现功能的最优方案是什么。这些最优方案就是我们需要的算法,这些算法可以提高用户的体验,减少硬件资源的消耗。
用这样的思路我们来实现以下数组去重算法:(这段代码折叠,大家可以先尝试自己写)
function unique(arr){var obj = {};var result = [];for(var i in arr){if(!obj[arr[i]]){obj[arr[i]] = true;result.push(arr[i]);}}return result; }
数组去重
算法入门之经典的排序算法详解
- 冒泡排序
- 选择排序
这里暂时介绍两种排序算法,就这两种排序算法介绍一些关于排序的应用场景解析,在前面的查重和去重算法中我们主要考虑到了效率。接着我们用这两个排序算法来将算法的解决特定问题引述出来,这两个算法并不能全面说明什么是特定的问题,它们仅仅只能告诉我们不同的算法存在其优点和缺点,适应的场景也就会随之发生变化,而这些场景往往来自不同的业务和功能的需求,需求来源不同,但可以根据其不同特性归类从而选择不同的算法,这就是算法的通用性。
1.冒泡排序(升序):
for(var j = 0; j < arr.length - 1; j++){for(var i = 0; i < arr.length - j - 1; i++){if(arr[i] > arr[i + 1]){var temp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = temp;}} }
首先我们就这这个升序的冒泡排序算法做一个图解,来理解冒泡排序的逻辑及其原理:
假设有数组:var arr = [5,3,7,2,8,6,1,9,4];
当外层循环第一次时:j == 0, i == 0。
通过一次外层循环,图解内部完全循环,可以看到冒泡循环就是通过两个相邻元素两两比较,升序就是将大值交换到后面的逻辑,每一次外层循环都可以获得对应循环终点的最大值。既然是两两比较,那么最一个单独的元素就不需要在循环比较了,所以外层循环也可以减去一次。
2.选择排序(升序):
for(var j = 0; j < arr.length - 1; j ++){var max = 0;for(var i = 0; i < arr.length - j - 1; i++){if (arr[i + 1] > arr[max]) {max = i + 1;}}var temp = arr[arr.length - j -1];arr[arr.length - j - 1] = arr[max];arr[max] = temp; }
选择排序的逻辑就是外层负责交换,内层负责找到对应一次外层循环终点内的最大值的索引,然后在一次外层循环结束时,将最大值与该次循环终点的元素进行交换位置。下面提供选择排序的图解:
假设有数组:var arr = [5,3,7,2,8,6,1,9,4];
第一轮外层循环
i [i+1]>[max] max
0 3>5 =>false 0
1 7>5 =>true 2
2 2>7 =>false 2
3 8>7 =>true 4
4 6>8 =>false 4
5 1>8 =>false 4
6 9>8 =>true 7
7 4>9 =>false 7
max=7;终点=8;
第二轮外层循环
i [i+1]>[max] max
0 3>5 =>false 0
1 7>5 =>true 2
2 2>7 =>false 2
3 8>7 =>true 4
4 6>8 =>false 4
5 1>8 =>false 4
6 4>8 =>false 4
max=4;终点=7;
第三轮外层循环
i [i+1]>[max] max
0 3>5 =>false 0
1 7>5 =>true 2
2 2>7 =>false 2
3 4>7 =>false 2
4 6>7 =>false 2
5 1>7 =>false 2
max=2;终点=6;
第四轮外层循环
i [i+1]>[max] max
0 3>5 =>false 0
1 1>5 =>false 0
2 2>5 =>false 0
3 4>5 =>false 0
4 6>5 =>true 5
max=5;终点=5;
第五轮外层循环
i [i+1]>[max] max
0 3>5 =>false 0
1 1>5 =>false 0
2 2>5 =>false 0
3 4>5 =>false 0
max=0;终点=4;
第六轮外层循环
i [i+1]>[max] max
0 3>4 =>false 0
1 1>4 =>false 0
2 2>4 =>false 0
max=0;终点=3;
第七轮外层循环
i [i+1]>[max] max
0 3>2 =>true 1
1 1>3 =>false 1
max=1;终点=2;
第八轮外层循环
i [i+1]>[max] max
0 1>2 =>false 0
max=0;终点=1;
通过上图将选择排序的处理逻辑可视化展示后,可以看到交换次数明显少于冒泡排序,但是借助了一个最大值索引变量来完成,这个变量会在每次外层循环时被创建,从这个角度来说对于空间的需求比冒泡排序要大。从效率的角度来讲选择排序的空间效率是肯定弱于冒泡排序,但是时间效率会如何呢?这个问题需要考虑更多的因素才能得到结果,由于这篇博客是基于入门级别的角度来阐述,所以暂时不探讨太深入的问题。
通过两个排序算法我们可以了解到解决同一个问题有多种方案,但是不同方案会有不同的优势和劣势,怎么在实际问题中应用这两个算法,需要对它们的优势和劣势进行深入的分析,这不在入门的范围内,后期会有博客更新算法知识点的深入理解部分。这篇博客旨在介绍算法是什么?我们如何对具体问题进行分析及编写算法,所以上面的两个排序算法还并不是我们能拿来解决具体问题的工具,我们还需要对其进一步逻辑分析和封装,修改成可以在需要是随时使用的函数。
- 排序算法需要做的核心工作是什么?
- 排序算法都有什么共同的特点?
这两个问题其实是一个问题,排序算法的核心工作就是【比较+交换】,这也是排序算法的共同特点,所以根据这个核心工作原理,上面两个排序算法可以封装成以下具体方法:
//比较 function compare(a,b){if (a > b) {return true;}else{return false;} } //交换 function exchange(arr,m,n){var temp = arr[m];arr[m] = arr[n];arr[n] = temp; } //封装冒泡排序 function bubbleSort(arr){for(var j = 0; j < arr.length - 1; j++){for(var i = 0; i < arr.length - j - 1 ; i++){if(compare(arr[i] , arr[i + 1])){exchange(arr,i,i+1)}}} } //封装选择排序 function selectionSort(arr){for(var j = 0; j < arr.length - 1; j ++){var max = 0;for(var i = 0; i < arr.length - j - 1; i++){if(compare(arr[i +1] , arr[max])){max = i + 1;}}exchange(arr,arr.length - j -1,max);} }
了解到这里,我们应该可以大概的理解算法的定义了:算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指定,算法代表着用系统的方法描述解决问题的策略机制。对于同一个问题我们又会有不同的策略机制,就拿排序算法来说,我们分析的就有两种了,但是并不止这两种,常见的排序算法还有快速排序、直接插入排序、希尔排序、堆排序、归并排序、基数排序。不同的排序算法有不同的应用场景,有时间再来更新深入分析算法的内容了,今天是大年初四,在这里祝福大家猪年好运,身体健康,猪定幸福!
想深入了解算法的话可以先参考这两个博客:
排序算法的稳定性
算法的复杂度
转载于:https://www.cnblogs.com/ZheOneAndOnly/p/10355397.html
前端工程师算法(一)相关推荐
- 七夕节马上要到了,前端工程师,后端工程师,算法工程师都怎么哄女朋友开心?
这篇文章的前提是,你得有个女朋友,没有就先收藏着吧! 七夕节的来源是梁山伯与祝英台的美丽传说,化成了一对蝴蝶~ 美丽的神话!虽然现在一般是过214的情人节了,但是不得不说,古老的传统的文化遗产,还是要 ...
- 前端工程师成长之多读好书
1 引言 乱七八糟的书看了很多,有一本讲JavaScript的印象特别深开篇说的是"JavaScript是Java的脚本语言",但还是看完了,最后忘了书名. 下面列的这些都是看过后 ...
- 「北京」「10-30k」「华米科技(小米手环)」招前端工程师
公司 华米科技 Huami, Inc. 华米科技创立于2013年,是一家在智能穿戴技术领域有着丰富生物特征识别经验和运动数据驱动的公司,拥有全球用户海量的生物识别与运动数据库,为用户提供综合评估及分析 ...
- Facebook 对前端工程师的要求是啥?一起来看看
原文作者:Dan Abramov 译者:UC 国际研发 Jothy 写在最前:欢迎你来到"UC国际技术"公众号,我们将为大家提供与客户端.服务端.算法.测试.数据.前端等相关的高质 ...
- 对前端来说token代表了什么_在线公开课 | 前端工程师如何突破瓶颈更好地变现自己...
课程概要 此次课程的分享主题是"前端工程师如何突破瓶颈更好地变现提升自己".课程从以下三个方面入手,为大家详解一个前端工程师是如何一步步完善并提升自己的的. 前端工程师所应具备的能 ...
- python工程师薪资坑吗-完美起航-20201024——记录一下自己的前端工程师之路
1. 前言 主要是想记录一下自己的历程: 是怎么就不明不白的成为了一名程序员 不知不觉得就进入了前端领域 怎么从小白到以为不是小白再到小白的过程 自己是如何学习的,计划如何学习的,如何走向下一步的 2 ...
- 【职场】看一位前端工程师如何上班摸鱼
这是对白的第 70 期分享 作者 l 霓虹(本文已获原创授权) 出品 l 对白的算法屋 大家好,我是对白. 今天给大家带来一篇我朋友霓虹写的摸鱼文章,他是一位前端工程师,擅长在公司里摸鱼,文笔清奇而搞 ...
- 未来,仅凭几个前端工程师,就能 hold 住一家企业吗?
简介: 微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员.团队的增加,从一个普通应用演变成一个巨石应用(Frontend Monolith),随之而来的应用不可维护问题.这类问题在企 ...
- 如何成为优秀的前端工程师
如何成为一名优秀的前端工程师 (share) 发现一篇不错的博文,和大家分享一下,为有志成为一名优秀前端工程师的童鞋们提供一个参考. :)~ 本文来源:http://www.biaodianfu.co ...
最新文章
- Django+JWT实现Token认证
- boost::core模块实现constexpr的地址
- 【es】es 分布式一致性原理剖析 节点篇
- 编译安装http启动问题
- jsp后台页面登录html代码,炫酷的登录jsp页面完整代码
- VPX,CompactPCI serial 总线
- 用计算机进行实时自动采集,动态数据采集
- ue4 FString 中文乱码问题
- elementUI中折叠面板箭头图标位置调整
- 2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest
- docker 安装kafka
- 有符号数和无符号数区别
- 语言-英语-英国英语:英国英语
- Go语言map的并发操作
- 基于深度学习和3D图像处理的精密加工件外观缺陷检测系统
- 软件安全性测试设计的基本原则
- MATLAB利用主成分分析进行综合评价排名
- 2022年中国隐私计算综合影响力 TOP10 企业
- java基础入门《一》
- 弟中弟的Leetcode总结——数组类(四)