js回忆录(3) -- 循环语句,前后缀运算符

计算机对于大批量数据的处理速度比起人类不知道快了多少,因此对于重复的操作,使用循环语句处理是很方便的,对于我们前端来说,给同一标签的元素绑定事件啦,tab切换啦,左右联动效果啦,等等都可以使用循环语句处理。js里边最基础的循环语句就是for和while两个了,其他的诸如:for... in遍历对象 ,for...of遍历数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)等,在此不作讨论。

for( 初始值...;条件...;某一增量...)

首先谈一下for循环,对于for循环来说,基本结构如上所示,三条语句都不是必须的,但是两个分号是必须的。(昨天撸了半天的文字忘记点修改了,结果php博客的本地保存功能一点都不好使,哎,今天继续码吧)

对于for循环来说,执行的时候小括号里边的前两条语句顺序执行,如果满足第二条条件语句,就执行循环体,完毕执行之后再做增量运算,然后重复以上步骤。而在这里边我要额外多说几句的是前后缀运算符的使用,因为我发现很多非科班出身的程序猿确实对这个不会,举个例子很容易就看明白了;

let a = 0,b = 0;
console.log( a++ ); //0
console.log( ++b ); //1
a; //1
b;//1

其实就是对值得引用时机不同,前缀运算符和变量那个在前就先引用谁的值。通常我们会使用for循环遍历一个数组,或者类数组对象,在写这篇文章的时候我也想到了一个遍历数组的方法:

function iteratorArr ( arr ) {
    if( !arr.length )
        return;
     let len = arr.length;
     if( len % 2 == 0 ){//偶数个元素
         for( let i = 0 ; i < len / 2 ; i++ ){
             arr[i];
             arr[len-i-1];
         }
     }else{//奇数个元素
         for( let i = 0 ; i <= (len - 1) /2; i++ ){
             if( i == (len - 1) /2 ){
             }else{
                 arr[i];
                 arr[ len - i -1 ];
             }
         }
     }
}

这个方法在10000000数量级以下的遍历数组中(我做的是累加操作),比传统for循环慢点,1000000个数的时候,比传统的慢了1毫秒,等于10000000这个数量级的时候比传统的for遍历数组快了两毫秒。测试环境实在chrome的console环境里弄的。所以处理轻量级的数据用for直接遍历就行了。貌似我们前端处理的数据量也远远没有这么高,所以这个方法基本作废,另外,其实我就是把一个数组一分为二,一次循环期间对数组的两个元素做一次操作,然而这样一个问题是,假如按照我的思路:就是假设一次循环操作的元素越多,那么算法性能越好的话,那么三分法,四分法,甚至五分法是不是性能会更优一点 ? 到底有没有最优解,这个我目前没法判断出来,而且,依照上面的判断的话,这样一直分下去似乎是一个无解的题,所以上面这个方法纯属自娱自乐了。但是于我个人而言,还是想写在这篇文章里,因为死了几个脑细胞啊。

值得一说的是,任何东西都会产生一个瓶颈问题,正是因为量变产生质变,为了解决性能问题,所以才产生了这些人类的智慧结晶,比如基本的查找排序算法,鉴于前边谈了一大堆的废话,下面介绍一个比较有意思的算法题(也算比较经典):

题目描述:简而言之就是在一个从左到右,从上到下递增的的二维矩阵里边找到一个值,而要求算法的时间复杂度为O(n).

//解法示例
function searchIndex ( arr, key ){
    let rows = arr.length - 1;
    let cols = arr[0].length-1,i = 0,j = cols ;
    while(  i <= rows && j >= 0){
        if(  key >  arr[i][j]){    
            i++;
        }else if( key < arr[i][j] ){
            j--;
        }else{
            return { i,j }
        }
    }
    return false;
}

这个解法是一种经典解法,用了两个指针,说到这里不得不提一个东西 --- 就是思维固化,人很容易思维固化的,乃至于你使用for循环的时候最开始的三条语句除了初始值,判断条件,增量之外写不出其他,一个tab除了全部隐藏,再显示的写法之外不会考虑其他的,是的,思维固化很可怕,但也很正常,在日复一日的码畜工作中逐渐丧失自我,不会思考。所以你的思维需要有东西去扩展,去打破,多看看那些经典算法是一个很不错的解决方案。回到上面那个问题,一般而言你往一个n*n的二维数组里找一个元素使用两重for循环是轻而易举的事,但是时间复杂度是o(n^2)的,浙大的陈姥姥说过,一旦出现这种复杂度的算法你就要警惕了,作为一个成熟的程序猿你得学会优化啊。而使用了两个指针之后,整个代码复杂度就降下来了 。当然这是一种特殊情况。

while

基本用法
while(expression){ 
    ...
    ...
 }

执行过程:先检测expressioin的值是否为true来决定是否执行循环体,说实话,我个人不怎么用。

基本循环语句先到这里,以后想到的话再补充。

posted @ 2017-10-26 09:56  子龙_子龙  阅读(12)  评论(0编辑  收藏  举报