Hello 2015

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

image.png 对象的思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
            var arr = [0,1,2,3,4,5,6,1,2,3,4,5,6,3,4,5,6];
            
            function appearOnce (arr , n) {
                var n = n || 1;
            	var obj = {};
            	var result = [];
            	  for(var i = 0; i < arr.length; i++) {
            	    if(obj[arr[i]]) {
            	      obj[arr[i]]++;
            	    }else {
            	      obj[arr[i]] = 1;
            	    }
            	  }
            	  
            	for(var prop in obj) {
            	  if (obj[prop] == n) {
            	  	result.push(prop);
            	  }
            	}
            	return result
            }
            var newArr = appearOnce(arr , n);
            console.log(newArr);
            
这么写实际上有个缺陷,
最终返回的数组中的类型都会变成 String
        
这个对象思路也能用于数组去重    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function appearOnce (arr) {
            	var result = [];
            	for(var i = 0; i < arr.length; i++) {
            	  if (arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])) {
            	  	result.push(arr[i]);
            	  }
            	}
            	
            	return result
            }
            var newArr = appearOnce(arr);
            console.log(newArr);

这个方法挺巧妙的, 但只能筛选出只出现一次的, 
出现多次的就无法筛选.

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var arr = [1,2,3,4,5,6,9,1,2,3,4,5,6];
            function appearOnce (arr) {
              var result = 0;
            	for(var i = 0; i < arr.length; i++) {
            	  
            	  result ^= arr[i];
            	}
            	return result
            }
            var a = appearOnce(arr);
            console.log(a);

这是利用了异或运算的特征
异或运算, 先把数字改成 二进制

每一位,不同为1.

特征是: a ^ a = 0
             a ^ 0 = a
             a ^ b ^ c = b ^ a ^ c

这里利用了, 偶数次异或相同的数字,会得0 的特征.
个人感觉,适用范围还挺狭窄的.

image.png 感觉这就是排序,找出最小值

1
2
3
4
5
6
7
8
            var arr = [1,5,3,3,8,4,9,3,5];
            function findMin(arr) {
              var newArr = arr.slice(0);// 为了 sort 不影响原来数组
              newArr.sort();
              return newArr[0];
            }
            var a = appearOnce(arr);
            console.log(a);
1
2
3
4
5
6
7
8
function appearOnce (arr) {
              var min = arr[0];
              for(var i = 1; i < arr.length; i++) {
                min = Math.min(min, arr[i])
// 这里也可以 这样  min = min >= arr[i] ? arr[i] : min;
              }
              return min
            }

老师为了涉及一下二分法思想,写了下面的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            var arr = [5,6,7,1,2,3,4];
            function searchMin (arr) {
              var mid = arr[Math.floor(arr.length / 2)];
              if (arr.length == 2) {
              	return Math.min(arr[0],arr[1]);
              }
              if(arr[0] >= mid) {
                var arr1 = arr.slice(0,mid + 1);
                return searchMin(arr1);
              }else{
                var arr1 = arr.slice(mid);
                return searchMin(arr1);
              }
            }
            var a = searchMin(arr);
            console.log(a);//5 有问题
但这个方法问题是很多的.
1. 天然的就会假定 arr[mid] 不是最小的.
2. 如果遇到 arr[0] == mid 时, 实际上 最小值 有可能在 左侧, 也有可能在右侧.
二分法排序是可以的. 用这种方法找最小值,似乎有问题.

image.png 先贴一下烂的, 我想了40分钟, 没写出来.感觉自己似乎还是菜鸟中的菜鸟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
            var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
            // 先把 一维数组, 改成二维数组
            // 可以改成 2*8 8*2 也可以改成 4 * 4
            // 我们假设 给定的数组长度是 某个数的平方
            
            function cons (arr) {
              var newArr = [];
            	var len = arr.length;
            	var xlen = Math.sqrt(len);
            	var k = 0;
            	for (var i = 0; i < xlen ; i++) {
            	  newArr[i] = [];
            	  for (var j = 0; j < xlen; j++) {
            	    newArr[i][j] = arr[k];
            	    k++;
            	  }
            	}
            	return newArr;
            }
            var newArr = cons(arr);
            console.log(newArr);
            
            // 顺时针 打印, 或者排序
            
            function print (arr) {
              var i = 0;
              var j = 0;
              var xlen = arr.length;
              var newArr = [];
              while (j != xlen){
                newArr.push(arr[i][j]);
                j++;
              }
              j = xlen - 1;
              while (i != xlen){
              	newArr.push(arr[i][j])
              	i++;
              }
              i = xlen - 1;
              while (j < 0){
              	newArr.push(arr[i][j]);
              	j--;
              }
              j = 0;
              while (i != 1){
              	newArr.push(arr[i][j]);
              	i--;
              }
              i = 1;
              while (j){
              	
              }
              
            	
            }
实在是太烂了, 写不下去.

董老师版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
function print (arr) {
            	
            	var direction = {
            	  "RIGHT" : {
            	    x : 1,
            	    y : 0
            	  },
            	  "LEFT" : {
            	    x : -1,
            	    y : 0
            	  },
            	  "UP" : {
            	    x : 0,
            	    y : -1
            	  },
            	  "DOWN" : {
            	    x : 0,
            	    y : 1
            	  }
            	}
            	
            	var xlen = arr.length ;
            	var ylen = arr[0].length ;
            	
            	var xMax = xlen - 1;
            	var yMax = ylen - 1;
            	var xMin = 0;
            	var yMin = 0;
            	
            	var nowDirection = direction.RIGHT;
            	
            	var x = 0;
            	var y = 0;
            	var result = [];
            	for(var i = 0; i < xlen * ylen; i++) {
            	  // 装进数组
            	  result.push(arr[y][x]);
            	  x = x + nowDirection.x;
            	  y = y + nowDirection.y;
            	  // 判断临界点,改变方向.
            	  if (x == xMax && y == yMin && nowDirection == direction.RIGHT) {
            	  	nowDirection = direction.DOWN;
            	  	console.log('down');
            	  	yMin++;
            	  } else if (x == xMax && y == yMax && nowDirection == direction.DOWN) {
            	  	nowDirection = direction.LEFT;
            	  	console.log('left');
            	  	xMax--;
            	  }else if (x == xMin && y == yMax && nowDirection == direction.LEFT) {
            	  	nowDirection = direction.UP;
            	  	console.log('up');
            	  	yMax--;
            	  }else if (x == xMin && y == yMin && nowDirection == direction.UP) {
            	  	nowDirection = direction.RIGHT;
            	  	console.log('right');
            	  	xMin++;
            	  } 
            	}
            	return result
            	
            }
            var lastArr = print(newArr);
            console.log(lastArr);
            
            
            
            
        </script>

瞬间,我就似曾相识..这是陈老师在设计模式贪吃蛇案例中写过的.

我写的和董老师写的相比之时, 突然感慨..

首先,差距是有的. 但董老师写的一看完, 实际上不难理解.

思维上的第一个飞跃是 #方向的设置. 这是空间上有了方向之后的概念. 我没有及早想到.

更关键的问题在于, 不难发现, 董老师写的代码中, 设置的变量数量是我的数倍.

变量足够多, 定义足够清晰, 整个架构就足够清晰, 思路也就越清晰.

我的问题在于,有一个思维定式. 因为前面几道题, 代码量很少, 变量很少. 注意力集中在,用更少的变量, 更巧妙的方法, 去完成需求. 觉得设置过多的变量是一种很臃肿的做法.

然后深深的感觉被打脸..

我觉得以往我写一些小案例的时候, 往往遇到很多头昏脑涨的情况时, 就跟今天的情况差不多.

总想从有限的变量,数据当中, 理出各种复杂的关系. 而实际上关系也不用太多, 只要稍微复杂一点, 我的大脑,感受到的困难程度 几何式的上升.

#总结, 对我来讲,应该走这样一种方法, 先把概念对应的,临界点对应的,关系对应的, 用变量标识出来. 根据这些变量整理完关系之后, 最后重新根据依赖关系,整理这些变量. 精简这些变量. 别耍聪明,还是这样更稳妥更有效率.