通过求解N皇后问题,介绍一种的javascript库的封装方法。
/**
* N:皇后数量
*/
var Queen = function (N) {
if (N <= 0) {
console.log('N is invalid');
return null;
}
// 确保每一次调用Queen都会生成一个新的对象
return new Queen.fn.init(N);
}
/**
* 原型构造
*/
Queen.fn = Queen.prototype = {
constructor: Queen,
init: function (N){
var c = [];
this.N = N;
this.res = [];
// 递归求解
this.traverse(c, 0);
// 为了支持链式操作
return this;
}
};
// init的原型对象指向Queen的原型,这样就通过init构造的对象就可以使用挂在Queen原型上的方法
Queen.fn.init.prototype = Queen.fn;
/**
* 递归求解
*
* c:临时存储放置情况数组
* row:层的序号
*/
Queen.fn.traverse =function (c, row) {
if (row === this.N) {
// 最后一层递归完毕,能够执行到此处说明求解成功,保存求解结果
this.res.push(c.slice(0));
} else {
// 循环每一列,进行检测
for (let col = 0; col < this.N; col++) {
// 对列进行标记
c[row] = col;
// 检查是否符合规则
if (this.check(c, row)) {
// 符合规则,继续递归下一层
this.traverse(c, row + 1);
}
}
}
}
/**
* 检查放置是否合规
*
* c:临时存储放置情况数组
* row:层的序号
* 说明:
* c[row] === c[i]:说明本层放置的位置与上一层放置的位置在同一列上
* row + c[row] === i + c[i]:说明本层放置的位置与上一层放置的位置在同一斜线上,斜线为反斜线
* row - c[row] === i - c[i]:说明本层放置的位置与上一层放置的位置在同一斜线上,
*/
Queen.fn.check = function (c, row) {
for (let i = 0; i < row; i++) {
if (c[row] === c[i] || row + c[row] === i + c[i] || row - c[row] === i - c[i]) {
return false;
}
}
return true;
}
/**
* 图形化显示指定序号的结果
*
* index:结果序号
*/
Queen.fn.printByIndex = function (index) {
if (index < 1 || index > this.N) return;
index--;
let arr = [];
for (let i = 0; i < this.N; i++) {
for (let j = 0; j < this.N; j++) {
arr[j] = (j === this.res[index][i]) ? '*': '-';
}
console.log(arr.join(' '));
}
}
使用
let q = Queen(10);
// 打印第一个结果
q.printByIndex(1);
温馨提示:N的值最高在10左右,不然你试试,小心累坏你的机器哦_