如何在平方矩阵中找到连续的符号序列

时间:2015-05-31 10:09:20

标签: javascript for-loop

我需要帮助找到正确的算法。我有一个二维数组,例如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"CellChat";

    self.customCell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (!self.customCell)
    {
        self.customCell = [[YourCellClass alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }

    // dont forget to set this

    self.customCell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    self.customCell.textLabel.numberOfLines = 0;
    // [self.customCell sizeToFit]; optional depending from what you want
    return self.customCell;
}

我想验证此数组是否有三个在任何方向上相互匹配的下一个符号(水平或垂直或交叉),然后显示此符号。

我这样做:

运行数组:

var arr = [
[""," "," "," ",""],
[""," "," "," ",""],
[""," "," ","X",""],
["","X","X","X",""],
[""," "," ","X",""]];

然后验证是否匹配:

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

但它并不计算最后一行。

我该怎么做?

3 个答案:

答案 0 :(得分:0)

你的循环应该在i < arr.length-2时停止,因为你想确保i+2在界限范围内。

答案 1 :(得分:0)

三个连续的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]);
            }
        }
    }
}

答案 2 :(得分:0)

您可以尝试连续计算每行,每列或对角线。

给定一个计算连续“X”

的步长函数
data = {
    succX = 0
};

function step (data, arr, i, j) {
    data.succX = arr[i][j] === "X" ? data.succX + 1 : 0;
    return data.succX >= 3;;
}

然后,您可以迭代并查找步骤结果。如果步骤返回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>