上一次讲了2048游戏关于处理一行数据的实现原理,对每一行的处理中针对数据为0的需要重新进行处理,效率略低
实现原理一:
//遍历数组从数组的的当前位置的下一个开始遍历,找不是0的位置() // 如果没找到什么也不做 // 如果找到 //如果当前位置是0,那么像当前位置与下一个进行互换(当前位置获得下一个位置的数据,并且将下一个位置数据置为0,将下标减一) //如果当前位置和下一个位置相等,将当前位置数据*2,下个位置数据置0
var getData = function(arr) { //遍历数组从数组的的当前位置的下一个开始遍历,找不是0的位置() // 如果没找到什么也不做 // 如果找到 //如果当前位置是0,那么像当前位置与下一个进行互换(当前位置获得下一个位置的数据,并且将下一个位置数据置为0,将下标减一) //如果当前位置和下一个位置相等,将当前位置数据*2,下个位置数据置0 var i,nextI,len,m; len = arr.length; for (i = 0; i < len; i += 1) { //先找nextI nextI = -1; for (m = i+1; m < len; m++){ if(arr[m] !== 0) { nextI = m; break; } } if (nextI !== -1) { //存在下个不为0的位置 if (arr[i] === 0) { arr[i] = arr[nextI]; arr[nextI] = 0; i -= 1; } else if (arr[i] === arr[nextI]) { arr[i] = arr[i] *2; arr[nextI] = 0; } } } return arr; };
实现原理二: 具体实现方法2:
var getDataArray = function(arr) { //遍历数组将其中的0去除,剩下的放入数组1中 //遍历数组1,当前位置与下一个是否相等如果相等,将当前位 的值 *2,下一位值 为0,同时下标加2,否则下标加1 //遍历数组1,将其中的0去除 得到数组2 //将数组2补齐到arr的长度,用0补 var getNonemptyArray = function(arr) { var i,len, targetArr = []; for (i = 0,len = arr.length;i < len;i += 1) { if (arr[i] !== 0) {targetArr.push(arr[i]); } } return targetArr; }; var i,len,targetArr = []; targetArr = getNonemptyArray(arr); if(targetArr.length === 0) { return arr} for(i = 0,len = targetArr.length;i < len;) { if(i < len -1 && targetArr[i] === targetArr[i + 1]) { targetArr[i] = targetArr[i] * 2; targetArr[i + 1] = 0; i += 2; }else{ i += 1 } } targetArr = getNonemptyArray(targetArr); for(i = 0,len = arr.length - targetArr.length; i < len; i += 1) { targetArr.push(0); } return targetArr; };
用这种方式进行操作的数据共遍历了4次;
用函数来测试两个方法的耗时
当数组中3000个数据的时候的运行结果。
var getRandomNumber = function() { return Math.random() > 0.4 ? 0 : Math.random() > 0.5 ? 2 : 4; }; var getTestDataArray = function(len) { var arr = []; for(var i = 0;i < len; i += 1) { arr.push(getRandomNumber()); } return arr; }; var time1,time2,testArr; testArr = getTestDataArray(30000); time1 = new Date(); getData(testArr); time2 = new Date(); console.log('方法一' + (time2 -time1)); time1 = new Date(); getDataArray(testArr); time2 = new Date(); console.log('方法二' + (time2 -time1));
运行结果:
方法一425 方法二3
可以看出方法二的效率要高很多。