JavaScript —— 算法思想之指针
《工欲善其事,必先利其器》
大家好,我是 vk 。关于《算法》
,我相信我们初中级的前端开发工程师们,光是听到这两个字都会闻风丧胆。当然了,除了我这个小菜鸡,早几年刚入行的时候,连算法二字都未曾听过。。。
一、什么是算法?
我相信,很多开发工程师们,对算法这方面的知识可能很薄弱。甚至是,不愿意去面对它,尤其是前端开发工程师。你是不是自己在心里这么想过:我是前端,又不是后端,为什么要管什么逻辑什么,我只需要做好自己的页面对接数据就好了,页面做得越炫酷,老板肯定会夸我加鸡腿!!
其实这么想就完全错了。
《 算法,不是只限制于某一个开发岗位,而是所有开发人员,都需要自修的一门课程,是编程人员的,基本素养。它是决定你的,编程能力和编程思维高低的一个决定性因素。》—— 我说的,不服只抽。(拽)
这时候可能会有小年轻发言了:说半天也没听出个啥来,算法到底是什么啊?是九九乘法表吗?关注这个干嘛?能涨薪水吗?我框架用的嘎嘎溜,两天搭建一个后台哦!!
你敢说:
- 曾几何时,你没有因为模板获取的数据格式和需要提交后端的数据格式对不上而苦恼过?
- 又或是,你没有因为后端返回的数据格式和某个插件和第三方库所需的数据格式不同,转来转去转半天都没有解决问题过?
- 还是说,你解决过某种问题了,实际上你根本不理解为什么这么处理数据,过后再次遇见这种问题还是继续苦苦百度?
实际上算法是,你在开发过程中,处理一些比较棘手的编程问题的时候,会用得上的一种编程方式,而不是简单的一门知识。
二、什么是指针?
C
语言,C++
,都有指针的概念,他们的指针是可以操作内存的;Java
没有指针,JavaScript
都没有指针的概念。
其实在不同的语言的 数据结构
内部,应该都是包含指针的。但是考虑到受众的接受能力,因此将指针包装隐藏起来了。在 Java
和 JavaScript
中与指针相关的主要是引用数据类型
里面。
在之前我写过的一篇文章中《Vue2.0 —— 实现 Mustache 模板引擎的数据结构和算法》,我们在收窄嵌套扁平 tokens
的时候,就运用到,栈 的数据结构思想。其中,我们利用了,JavaScript 的引用数据类型的特性,利用指针,把收集器(Collector
)永远指向当前的工作栈对象:
然而,如果我们不去运用这种指针的思想
,非常单纯的依靠判断,实现对数据的一个收窄工作,那么它的代码实际上是这样的:
// ...
switch(token[0]) {
case "#":
// 设置子项为空数组,进而继续收窄
token[2] = [];
// 收集进栈
sections.push(token);
break;
case "/":
// 出栈
let section_pop = sections.pop();
// 判断是否存在工作栈
if (sections.length > 0) {
// 如果有就需要把子项 push 到栈顶的工作栈中
sections[sections.length - 1][2].push(section_pop);
} else {
nestedTokens.push(section_pop);
};
break;
default:
// 判断是否存在工作栈
if (sections.length > 0) {
// 如果有就需要把子项 push 到栈顶的工作栈中
sections[sections.length - 1][2].push(token);
} else {
nestedTokens.push(token);
};
}
// ...
这样写的代码不仅不优雅,而且看起来还非常的繁琐。每次收窄数据都需要做判断,如果数据量大的话,这种做法其实是非常 低效
的。
三、算法的指针思想
而算法的 指针思想
,并不是指数据结构中的指针,相反,指针算法意味着一种思想,是一种解决问题的方式。
例如,我们先来看一道题目:
- 请寻找出字符串中,连续重复次数最多的字符;
- 以
var str = "aaaaaabbbbbbbbcccccccccccccccccccddddd";
字符串为例。
如果把这串字符串看成一条队伍,我们可以通过设置两个变量,分别当作两个手指(指针
),一个固定在队头,一个从队头开始移动,一个个走,以寻找是否有相同于队头的字符串。因此,我们可以这样写:
// 试寻找字符串中,连续重复次数最多的字符
var str = "aaaaaabbbbbbbbcccccccccccccccccccddddd";
// 指针
var i = 0;
var j = 1;
// 当前重复次数最多的次数
var maxRepeatCount = 0;
// 当前重复次数最多的字符串
var maxRepeatChar = "";
// 当 i 还在范围的时候,应该继续寻找
while(i <= str.length - 1) {
if (str[i] != str[j]) {
console.log("报!!!" + i + "和" + j + "之间的文字连续相同!!都是字母" + str[i] + "出现了" + (j - i) + "次!!" );
if (j - i > maxRepeatCount) {
maxRepeatCount = j - i;
maxRepeatChar = str[i];
}
i = j;
}
j++;
}
console.log(maxRepeatChar + "重复了" + maxRepeatCount + "次,是重复次数最多的字符");
随后看一下解出来的效果:
有了指针的思想,我们可以很轻松的,解决掉这个问题~
四、总结
总而言之,指针
,不单单是指某种语言中的一个概念,更多的时候它体现的是一种思想
。在数据结构和算法中,指针通常会被用于比较。例如比较大小、比较次数的多少,又或是模板编译中利用指针进行遍历的一种编程方式。后续我还会继续发布关于递归和栈的算法文章,希望你会喜欢。
最后,感谢你的阅读。