LBL法还原魔方

我写的东西,自己都看不懂

魔方的基本结构

国际标准的魔方(Rubik’s Cube) 由黄蓝红绿橙白6个中心块,8个角,12个棱,组成。
魔方颜色的位置关系是:上黄下白,前蓝后绿,左橙右红。

魔方入门级复原步骤 原参考链接

LBL(Layer By Layer)法,复原过程以上黄下白为例。

第一层

目标:复原最下面一层:底面复位,层面看可以构成四个凸型

首先,不在意侧面颜色,将四个白色棱块移动到上方(白面朝上),转动上层,将白色棱块侧面颜色移动到对应的面,180旋转侧面,将白色棱块移动到底部。
然后,使用左手或者右手公式,将上方的角块移到下方对应的夹角处。如果颜色方向不符合,就使用同一公式多转几次。

第二层

目标:复原中层的四个棱 - 完成两层

现在底面已经复原,侧面看四个小凸型也完成,使用左手公式-整体右转-右手公式(或者 右手公式-整体左转-左手公式)将上方的棱块移动到中层。

第三层(顶面)

目标:顶面复原

首先,使用拐角或者一字公式,将顶面复原成十字。
然后连续的使用左小鱼或者右小鱼,先转出左(右)小鱼型的顶面,再对应的解决掉,就完成了顶面。

第三层(侧面)

目标:完全复原

观察顶层侧面的颜色结构,如果发现有至少一对眼,就将有眼的一面放到左手,做一遍一字公式+拐角公式;如果没有眼,就做一遍拐角公式+一字公式;如果全是眼….就进行下一步。
(此时顶层的四个顶角应该都已经复原了)使用左小鱼-上层右转-右小鱼(或者右小鱼-生成左转-左小鱼),可以将面前的两个角块和左侧(右小鱼起手则是右侧)的棱块移动到一起,这样魔方就复原了。

JavaScript 两种常用的函数定义方法

JavaScript中定义函数,通常会遇到以下两种写法:

写法A

1
2
3
function name1(){
//...
}

写法B

1
2
3
var name2 = function(){
// ...
};

这两种写法有什么区别呢?很久很久以前,stackoverflow上面有人问了一样的问题。

funciton的基本定义

首先,在JavaScript中function的最基本定义方法是写法A,这种定义的内容在脚本被编译时就会执行,生成一个有名字的函数对象。

而写法B实际上是定义了一个无名的函数对象,又将这个对象赋给了一个有名字的变量。
这种写法的存在,方便了我们将函数定义为对象的属性:

1
2
3
4
5
var target = new Object();
target.add = function(a,b){
return a+b;
};
target.add(1,1); //2

所以写法A定义的是一个完整的函数对象,而写法B定义的函数是没有名字的,name2是变量的名字,而不是函数的。

扩展

其实还可以使用new来声明函数:

1
var name = new Function("a", "b", "return a+b;");

这里注意使用的是Function而不是function,这是具体的定义了一个Function类型的对象。速度慢,只有在特定情况下使用,比如想要让用户去控制函数内容的时候。

Immediately_Invoked_Function -- 立即调用函数的写法

自执行-立即调用的函数表达式

在某些情况下,我们不需要函数创建多个实例,也不需要对返回值做什么处理,便可以通过在函数声明的后面添加()来实现自执行。因为foo仅仅是function(){}这个表达式的一个引用,在函数表达时候后添加()便可以执行。

1
2
3
var foo = function(){
//do something.
}();

但如果我们像下面这么写,会报错:

1
2
3
function(){
//do somthing.
}();

给括号里加入参数的话,可以不报错,但是函数不会执行,因为它会被解析成一个毫不相关的括号。
报错原因:解析代码的时候,function已经被识别为声明函数用,而不是一个函数表达式。
所以我们要做的就是把括号前面的内容解析成表达式,以下的写法都可以:

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
(function makeCounter(){
console.log("invoked by ()");
}());

var x = function makeCounter(){
console.log("invoked by var with ()");
}();

!function(){
console.log("invoked by !");
}();

~function(){
console.log("invoked by ~");
}();

+function(){
console.log("invoked by +");
}();

-function(){
console.log("invoked by -");
}();

new function(){
console.log("invoked by new");
};

new function(){
console.log("invoked by new with ()");
}();

Java 中的NaN

介绍

在学习JavaScript时看到了Number类型中的NaN和Infinity,因为概念本身是通用的,所以趁机总结了一下Java中的NaN和Infinity。

基本

Java的Float型和Double型各有三个很特别的常量:NaN(非数),POSITIVE_INFINITY(正无穷),NEGATIVE_INFINITY(负无穷)

Float

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* A constant holding the positive infinity of type
* {@code float}. It is equal to the value returned by
* {@code Float.intBitsToFloat(0x7f800000)}.
*/
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;

/**
* A constant holding the negative infinity of type
* {@code float}. It is equal to the value returned by
* {@code Float.intBitsToFloat(0xff800000)}.
*/
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;

/**
* A constant holding a Not-a-Number (NaN) value of type
* {@code float}. It is equivalent to the value returned by
* {@code Float.intBitsToFloat(0x7fc00000)}.
*/
public static final float NaN = 0.0f / 0.0f;

Double

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* A constant holding the positive infinity of type
* {@code double}. It is equal to the value returned by
* {@code Double.longBitsToDouble(0x7ff0000000000000L)}.
*/
public static final double POSITIVE_INFINITY = 1.0 / 0.0;

/**
* A constant holding the negative infinity of type
* {@code double}. It is equal to the value returned by
* {@code Double.longBitsToDouble(0xfff0000000000000L)}.
*/
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

/**
* A constant holding a Not-a-Number (NaN) value of type
* {@code double}. It is equivalent to the value returned by
* {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
*/
public static final double NaN = 0.0d / 0.0;

NaN

NaN是Not a Number的缩写,表示未定义或者不可表示的值,NaN有一个特性,那就是它与任何数都不相等,包括它自己。判断一个数是不是NaN,只能使用Float或者Double的isNaN()方法,那么这个方法是怎么判断的呢?我们看一看(查看的是Float版,Double除了参数类型都一样,下面二者没有区别的部分都直接使用Float的内容来说明):

1
2
3
4
5
6
7
8
9
10
11
/**
* Returns {@code true} if the specified number is a
* Not-a-Number (NaN) value, {@code false} otherwise.
*
* @param v the value to be tested.
* @return {@code true} if the argument is NaN;
* {@code false} otherwise.
*/
public static boolean isNaN(float v) {
return (v != v);
}

所以,跟自己不相等的数字,就是NaN.

计算中产生的NaN

什么时候会产生NaN呢?首先,任何与NaN进行的运算,其结果都是NaN.比如下面的运算,不要去想太多,结果就是NaN

1
2
3
4
5
6
7
public class Test {
public static void main(String[] args) {
var x = Float.NaN;
var y = x - x + 1;
System.out.println(y);
}
}

其次,从数学角度讲,无法进行的运算(N/0)或者会产生复数的运算(sqrt(-N)),都会产生NaN。

(咕咕咕,后面的笔记被鸽了)

JavaScript 基本知识备忘录

介绍

JavaScript使用的是ECMA(European Computer Manufacturers Association)的ECMAScript标准,也就是人们常说的ES6,ES7,ES8.而JavaScript本身是网景公司(Netscape)对ES标准的一种实现,JavaScript是该公司的注册商标.(这也是前阵子苹果下架了所有名称里带JavaScript的app的原因)

JavaScript 是Brendan Eich用两周写出来的一种语言.所以有点设计缺陷也可以理解,比如typeof null == "object"
由于浏览器确定了使用的JavaScript版本,所以写JavaScript程序时,要注意ES版本与浏览器的支持是否匹配.

基本

写在哪里

JavaScript的代码可以直接写在网页html里,也可以单独写在js文件中.
html里的JavaScript代码要写在 <scrpt> 标签内,标签的 type 属性不需要定义:

1
2
3
4
5
6
7
8
9
10
11
<head>
<script>
alert('Hello, World!');
</script>:
</head>
<body>
...
</body>
</html>```

我们也可以把```alert('Hello, World!')```单独写在一个js文件中,取个名字`hello.js`,然后把js文件的引用写入html的head中(其实写在body里也能跑)
...
1
2
3
4
5
6
7

### 简单语法
JavaScript每个语句以`;`结束,JavaScript的引擎会自动添加,所以这里并不强制要求,不过因为自动添加的`;`有时会造成歧义,所以手动添加还是最保险的.

赋值语句
```JavaScript
var x = 1;
条件判断
1
2
3
if( 1 > 0 ){
x = 1;
}

一般规范:4空格缩进,80字换行

另外跟Java一样,JavaScript的注释写法也是///* */,JavaScript也对大小写敏感.

变量

  1. JavaScript是动态语言,变量的声明使用var,赋值使用**=**.
  2. 使用var声明的变量其作用域都在函数内,而不使用var声明的变量则是全局变量.
  3. 变量名要求由大小写英文,数字,$_组成,不可以用数字开头,也不可以使用JavaScript的关键字作为变量名.

数据类型

基本型

JavaScript有五种基本类型:

  • number
  • string
  • boolean
  • undefined
  • null
1
2
3
4
5
typeof 1;//"number"
typeof "abc";//"string"
typeof true;//"boolean"
typeof undefined;//"undefined"
typeof null;//"object"

数字型 Number

JavaScript中数字型不区分整数和浮点数,正、负、整数、浮点数、NaN、Infinity都是Number型,可直接进行运算.

NaN: Not a Number

Infinity: ∞ 无穷大

字符串

JavaScript中字符串可以用双引号",也可以用单引号'来表示.

布尔型

JavaScript中的布尔型由true和false构成,以及 与,或,取反的运算都与Java相同.

JavaScript中进行比较的时候,如果使用==,会自动转换类型再进行比较,不转换类型的比较则需使用三个等号===.

NaN与所有Number都不相等,包括它自己,判断NaN的时候只能使用isNaN().

1
2
3
4
isNaN(NaN) //true
>// function isNaN(a){
>// return a != a;
>// }

JavaScript的浮点数在运算时会产生误差,直接进行比较会出现错误结果.这点在Java中也是一样,所以要进行精确比较的时候,不应该使用浮点型.  

可以通过检测误差绝对值来进行比较:

1
Math.abs(1/3 - (1 - 2/3)) < 0.000001; \\true

空值和未定义

JavaScript中类似于Java,也通过null来表示空值,空值与长度为零的字符串不同.JavScript同时还定义了一个表示未定义的常量undefined.一般在检测参数时可以用到,未输入的参数会被当做undefined处理.

引用类型

数组 Array

JavaScript通过[]来表示数组,使用,来分隔元素.也可以用new Array(1,2,3);来定义数组.数组中的元素可以是任意的数据类型,通过索引arr[index]来访问.

对象 Object

JavaScript的对象是由成对的key-value组成的无序集合.key都是字符串,value可以是任意数据类型.

1
2
3
4
5
6
7
var person = {
name: 'Bob',
age: 23,
tags: ['person', 'young'],
married: false,
code: null
}

通过以下格式获取对象的属性:

1
2
person.name;// Bob
person.age; // 23

作用域

传统的编程语言,作用域一般是块级,也就是一个{}内是一个作用域,所以在if else while for的范围内定义的局部变量不会影响到外面.而JavaScript的作用域是函数级,一个function为一个作用域,在函数内部定义的变量,不受函数内部语法块的影响.

1
2
3
4
5
var x = 1; // 1
if(true){
var x = 2; //2
}
condole.log(x); //2

如果一定要实现块作用域的话,便需要插入函数来起到划分的作用

1
2
3
4
5
6
7
var x = 1; //1
if(true){
function print(){
var x = 2;//2
}
}
console.log(x);//1

函数作用域提升

函数声明分为:声明式 和 变量式

声明式会自动将声明放在函数最前面,并执行赋值的内容.

1
2
3
function name(){

}

所以下面的函数没有问题

1
2
3
4
test("test");
function test(arg){
console.log(arg); //test
}

变量式会将声明提升到函数最前,而后再赋值

1
2
3
var name = funciton(){

}

所以下面的代码中,函数被声明之后,还没有赋值,便被执行,会报错.

1
2
3
4
baz("baz"); //baz is not a function
var baz = function(arg){
console.log(arg);
};

需要注意的是,变量式声明中的函数,是不会被提升作用域的

1
2
3
4
5
6
7
8
9
var baz = function spam(arg){
if(arg < 5){
spam(arg + 1);//只在函数的作用域内有效
}else{
console.log(arg);
}
};
baz(1); //5
spam(1);//spam is not defined

使用var声明的变量或者函数,要放到其作用域的顶端.

IDE使用备忘录

“这里应该怎么设置来着? ”

Eclipse

Web Application Library添加本地jar包

在项目上右键 -> Deployment Assembly -> add -> project.

显示/隐藏 空白符号

Windows/Preferences/General/Editors/Text Editors
通过勾选 Show whitespace characters 来设置是否显示空白符号
点击右侧的configure visibility,还可以进行具体(比如换行符)的设置.

隐藏状态

显示状态

Intellj IDEA

propertity文件相关

显示文字而不是ASCII编码

直接打开propertity文件的话,UTF-8编码会直接显示ASCII编码而不是文字,可以在设置里修改:
File -> Setting -> Editor -> File Encoding

大约中间靠下的位置,勾选
transparent native to ascii conversion
就可以显示文字而不是直接显示ASCII编码了。

修改ASCII编码的默认大小写

使用ASCII码的property文件在IDEA中编辑会默认使用大写字母(例:使用 \u00E3 而不是 \u00e3)
如果想要保存成小写字母,需要在IntellJ的根目录下找到 idea.properties,在其中添加:
idea.native2ascii.lowercase=true

Markdown 语法笔记

内容整理自 markdowntutorial.

粗体和斜体

斜体

_Italic_
输入内容的前后添加下划线,使字体变为斜体。

粗体

**Bold**
输入内容的前后添加星号,使字体变为粗体。

删除线

~~删除线~~
输入内容的前后加波浪线,在文字上添加删除划线。

标题

1
2
3
4
5
6
# Header one
## Header two
### Header three
#### Header four
##### Header five
###### Header six

链接

完整的链接

[XSUN的主页](https://xsun4231.github.io/)
效果: XSUN的主页
链接的书写格式: 方括号+圆括号的组合 方括号内为页面显示内容,圆括号内为链接URL

参照

1
2
3
4
5
[从这里进入][url名]
[从这里也可以][url名]
[这里也行][url名]

[url名]: https://xsun4231.github.io/

从这里进入
从这里也可以
这里也行

设置参照与设置链接方法基本相同,只是在链接URL前面单独设置一个标签,标签可反复使用。

插入(图片)

![这是一张很可爱的图片](https://octodex.github.com/images/spidertocat.png)

这是一张很可爱的图片

图片的是指方法与链接的设置方法基本相同,只是在方括号前面添加叹号。

图片的链接同样可以设置为参照

引用

> 孟子曰:孔子说的对。

孟子曰:孔子说的对。

在文字块(以换行结束)前添加大于号(右尖括号),则将整个文字块设置成引用。
将多个段落设置成一个引用块时,在每一个新段落(换行后)添加大于号。

列表

1
2
3
4
5
6
7
8
9
10
11
* milk
* egg
* apple
1. fuji
2. fuji2
3. fuji3
* banana
* people
1. AAA
1. BBB
1. CCC
  • milk
  • egg
  • apple
    1. fuji
    2. fuji2
    3. fuji3
  • banana
    1. AAA
    2. BBB
    3. CCC

列表用星号来标记,在星号前添加缩进来增加层次,使用数字代替星号可以将标签变为数字。

段落

1
2
3
第一段
第二段
第三段

代码块外的单一换行不会被识别,可以使用多个换行来制造强制换行,不过会造成很大的间距。

第一段
第二段

第三段

标准的换行是在行位添加两个空格:

第一段
第二段
第三段

代码块

1
2
3
4
5
6
7
@requires_authorization
class SomeClass:
pass

if __name__ == '__main__':
# A comment
print 'hello world'

` 是键盘左上角Esc下面那个,不是单引号’

1
2
3
4
5
6
7
8
9
10
三个` 
@requires_authorization
class SomeClass:
pass

if __name__ == '__main__':
# A comment
print 'hello world'

三个`

图表

1
2
3
4
5
| ID     | NAME | AGE   |
| :---- | ----: | :---: |
| 00001 | AAAA | 5 |
| 002 | BB | 12 |
| 03 | CCC | 9 |
ID NAME AGE
00001 AAAA 5
002 BB 12
03 CCC 9