如何在一个方阵中找到一个连续的符号序列
How to find a consecutive sequence of symbols in a squared matrix
我需要帮助找到正确的算法。我有一个二维数组,例如:
var arr = [
[""," "," "," ",""],
[""," "," "," ",""],
[""," "," ","X",""],
["","X","X","X",""],
[""," "," ","X",""]];
我想验证这个数组是否有三个在任何方向(水平或垂直,或交叉)上相互匹配的下一个符号,然后显示这些符号。
我是这样做的:
Run through array:
for(var i = 0; i < arr.length; i+=1){
for(var j = 0; j < arr.length; j+=1){
验证是否匹配:
if(arr[i][j] == "X" && arr[i+1][j] == "X" && arr[i+2][j] == "X"){
console.log(arr[i][j]);
但是它会给出一个错误,因为i+1
和i+2
在数组后面。
我试着验证如果:
if(arr[i][j+1] < arr.length)
但是它不计算最后一行
我该怎么做?
您可以尝试对每一行、每一列或每一条对角线进行连续计数。
给定一个阶跃函数,计算连续的"X"
data = {
succX = 0
};
function step (data, arr, i, j) {
data.succX = arr[i][j] === "X" ? data.succX + 1 : 0;
return data.succX >= 3;;
}
然后,您可以迭代并查找步骤结果。如果step返回true
,则存储相应的序列并停止搜索。
遍历每一行
for (var i = 0, nbRow = arr.length; i < nbRow; i++) {
for (var j = 0, nbCol = arr[i].length; j < nbCol; j++) {
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i, j-2], [i, j-1], [i, j]];
}
}
data.succX = 0;
遍历每一列
for (var j = 0, nbCol = arr[0].length; j < nbCol; j++) {
for (var i = 0, nbRow = arr.length; i < nbRow; i++) {
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i-2, j], [i-1, j], [i, j]];
}
}
遍历每个对角线
for (var d = 0, dim = arr.length, nbDiag = dim * 2 - 1; d < nbDiag; d++) {
var maxE = d >= dim ? nbDiag - d - 1 : d;
for (var e = 0; e <= maxE; e++) {
var i = Math.min(d, dim -1) - e,
j = Math.max(0, d - dim + 1) + e;
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i, j-2], [i+1, j-1], [i+2, j]];
}
data.succX = 0;
}
for (var d = 0, dim = arr.length, nbDiag = dim * 2 - 1; d < nbDiag; d++) {
var maxE = d >= dim ? nbDiag - d - 1 : d;
for (var e = 0; e <= maxE; e++) {
var i = dim - 1 -Math.min(d, dim -1) + e,
j = Math.max(0, d - dim + 1) + e;
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i-2, j-2], [i-1, j-1], [i, j]];
}
data.succX = 0;
}
最后,data.winSeq
包含未定义序列或有效序列。
您可以在下面的代码片段中看到整个过程。
var delay = 0;
function findWinSeq(arr, seqLength) {
var data = { succX: 0 };
// Iteration step
function step (data, arr, i, j) {
if (arr[i][j] === "X") {
data.succX++;
colorize(i, j, "validCell", delay);
} else {
data.succX = 0;
colorize(i, j, "selectCell", delay);
}
var hasWon = data.succX >= seqLength;
delay += hasWon ? 2000 : 120;
return hasWon;
}
// Count for each row
for (var i = 0, nbRow = arr.length; i < nbRow; i++) {
for (var j = 0, nbCol = arr[i].length; j < nbCol; j++) {
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i, j-2], [i, j-1], [i, j]];
}
}
data.succX = 0;
// Count for each column
for (var j = 0, nbCol = arr[0].length; j < nbCol; j++) {
for (var i = 0, nbRow = arr.length; i < nbRow; i++) {
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i-2, j], [i-1, j], [i, j]];
}
}
// Count for each diagonal
for (var d = 0, dim = arr.length, nbDiag = dim * 2 - 1; d < nbDiag; d++) {
var maxE = d >= dim ? nbDiag - d - 1 : d;
for (var e = 0; e <= maxE; e++) {
var i = Math.min(d, dim -1) - e,
j = Math.max(0, d - dim + 1) + e;
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i, j-2], [i+1, j-1], [i+2, j]];
}
data.succX = 0;
}
for (var d = 0, dim = arr.length, nbDiag = dim * 2 - 1; d < nbDiag; d++) {
var maxE = d >= dim ? nbDiag - d - 1 : d;
for (var e = 0; e <= maxE; e++) {
var i = dim - 1 -Math.min(d, dim -1) + e,
j = Math.max(0, d - dim + 1) + e;
data.winSeq = data.winSeq || step(data, arr, i, j) && [[i-2, j-2], [i-1, j-1], [i, j]];
}
data.succX = 0;
}
return data.winSeq || null;
}
var tests = [
[
[" "," "," "," "," "],
[" ","X"," ","X"," "],
[" "," ","X"," "," "],
[" "," "," ","X"," "],
[" ","X"," "," "," "]
],
[
[" "," "," "," "," "],
[" ","X"," ","X"," "],
[" "," "," "," "," "],
[" "," "," ","X"," "],
[" ","X"," "," "," "]
],
[
[" "," "," "," "," "],
[" ","X"," ","X"," "],
[" "," "," "," ","X"],
[" "," "," ","X"," "],
[" ","X","X"," "," "]
],
[
[" "," "," "," "," "],
[" "," "," ","X"," "],
[" "," ","X","X"," "],
[" "," "," ","X"," "],
[" ","X"," "," "," "]
],
[
[" "," "," "," "," "],
["X","X","X","X"," "],
[" "," ","X"," "," "],
[" "," "," ","X"," "],
[" ","X"," "," "," "]
],
];
// Just some fancy stuffs
function colorize(i, j, color, delay) {
function _colorize(i, j, color) {
// Reset first valid cell if needed
if (color === "selectCell") {
var cells = document.getElementsByClassName("validCell");
for(var k = 0, cell; cell = cells[k]; k++) {
cell.className = "cell";
}
}
// Apply color to the next cell
var previous = document.getElementsByClassName("selectCell")[0];
if (previous !== undefined) { previous.className = "cell"; }
document.getElementById([i,j].join("")).className = color;
}
setTimeout(_colorize, delay, i, j, color);
}
function buildBoard (test) {
var board = document.getElementById("board");
board.style.width = test.length * 40 + "px";
board.innerHTML = "";
for (var i = 0, marker, cell, dim = test.length; i < dim; i++) {
for (var j = 0; j < dim; j++) {
cell = document.createElement('div');
cell.className = "cell";
cell.id = [i,j].join("");
if (test[i][j] === "X") {
marker = document.createElement('div');
marker.className = "marker";
cell.appendChild(marker);
}
board.appendChild(cell);
}
}
}
for (var i = 0, test; test = tests[i]; i++) {
setTimeout(function (test) {
setTimeout(function (test) {
buildBoard(test);
}, delay, test);
findWinSeq(test, 3);
}, 750 * i, test);
}
#board {
padding: 0;
margin: 0;
font-size: 0;
}
.cell, .validCell, .selectCell {
display: inline-block;
box-sizing: border-box;
border: 1px solid #888;
width: 40px;
height: 40px;
}
.validCell {
background: #CDEB8B;
}
.selectCell {
background: #DDD;
}
.marker {
background: #888;
width: 16px;
height: 16px;
margin: 12px 0 0 12px;
}
<div id="board"></div>
你的循环应该在i < arr.length-2
时停止,因为你想确保i+2
在边界内。
三个连续的X符号由它们的中心和方向(水平、垂直或两条对角线之一)唯一定义。我会这样做(谢谢@DarthJS):
for (var i = 0; i < arr.length; i+=1) {
for (var j = 0; j < arr.length; j+=1) {
// Horizontal
if (i > 0 && i < arr.length - 1 &&
arr[i-1][j] == "X" && arr[i][j] == "X" && arr[i+1][j] == "X") {
console.log(arr[i][j]);
}
// Vertical
if (j > 0 && j < arr.length - 1 &&
arr[i][j-1] == "X" && arr[i][j] == "X" && arr[i][j+1] == "X") {
console.log(arr[i][j]);
}
// Diagonal
if (i > 0 && i < arr.length - 1 &&
j > 0 && j < arr.length - 1) {
if (arr[i-1][j-1] == "X" && arr[i][j] == "X" && arr[i+1][j+1] == "X") {
console.log(arr[i][j]);
}
if (arr[i-1][j+1] == "X" && arr[i][j] == "X" && arr[i+1][j-1] == "X") {
console.log(arr[i][j]);
}
}
}
}
相关文章:
- AngulsrJS $filter orderby 一个带有 @ 符号的数组键
- JavaScript 不会替换字符串的最后一个符号
- 在 Javascript 中获取字符串中的最后一个符号时值错误
- 从引导程序图标十六进制值输出一个符号
- Caret函数没有'如果插入符号在最后一个位置,就不能正常工作
- 我如何判断一个符号是否被用作密钥
- 所有有效的电子邮件是否至少包含一个@符号
- 如何避免 url 自动在 ajax 请求后附加一个“#”符号
- 使用jquery将除文本字段和文本区域外的所有html标记中的所有指定符号转换为另一个符号
- 为什么在下面的例子中零有一个符号
- 在文本区域的每个指定长度后面添加一个符号
- 用highchart设置一个符号标记
- 在最后一个符号"/"或““
- Regex比需要多提取一个符号
- 在jQuery中使用html()方法和一个符号
- 如何在一个符号的每一边得到数字
- 函数将参数更改为另一个符号
- 在页面上的所有文本框前面添加一个$符号
- 为什么这个regex替换会在开头删除一个符号,而不是在结尾
- 正则表达式有一个例外 - 如果数字是下一个符号,则不要匹配所有内容