Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 匹配给定n*m矩阵中序列的算法_Algorithm - Fatal编程技术网

Algorithm 匹配给定n*m矩阵中序列的算法

Algorithm 匹配给定n*m矩阵中序列的算法,algorithm,Algorithm,我有一个n*m维的矩阵,我想用给定的矩阵匹配一组数字。如果模式落在矩阵的垂直或水平列中,这是非常直接的,但是如果模式以对角线的方式落下,我无法检测到它。 例如,如果我必须匹配以下矩阵中给定的模式[-1,-1,-1] 0 0-10 0-10 0 0-100 10-1-1-1 在上面的例子中,我应该能够以对角线的方式检测到-1组以及最后一行中的一组 我也可以在其中输入 -100-10 0-100 0-1-10 0 10-1-1-1 在这种情况下,将检测从右到左的对角线以及最后一行序列。 基本上,在一

我有一个n*m维的矩阵,我想用给定的矩阵匹配一组数字。如果模式落在矩阵的垂直或水平列中,这是非常直接的,但是如果模式以对角线的方式落下,我无法检测到它。 例如,如果我必须匹配以下矩阵中给定的模式[-1,-1,-1]

0 0-10

0-10 0

0-100

10-1-1-1

在上面的例子中,我应该能够以对角线的方式检测到-1组以及最后一行中的一组

我也可以在其中输入

-100-10

0-100

0-1-10 0

10-1-1-1

在这种情况下,将检测从右到左的对角线以及最后一行序列。 基本上,在一个给定的序列上,我必须能够检测到它的存在,它可以是垂直的,也可以是水平的或对角的

我的问题是:算法必须检测“所有”序列,而不管它是水平、垂直还是对角存在。另外,请记住矩阵的维数是N*M,因此它可以是任意大小。

我会注意到,您可以(有点详尽地)以不同的步幅(1,M-1,M,M+1)在N行x M列矩阵(视为单个向量)上迭代。在每一步中,从每一个位置开始(直到该步从向量末端开始),然后查看是否有匹配项

这至少消除了水平、垂直和两条对角线的四种不同算法

不过,就算法顺序而言,相当难看——相当于N平方


(好吧,也许不是。你可以用一个循环来限定起始单元格的所有四种可能性。因此,一旦找到起始单元格,检查四个步幅。这样你就可以通过一次基本的矩阵检查所有内容。)

不管优化技术如何,这个问题的更一般版本如下:

您有一个元素数组,其中每个元素都是一个数字及其相对位置

例如,从左到右的数字列表60,50,40,30看起来像(60,0,0)(50,1,0)(40,2,0)(30,3,0)。如果这是一个自上而下的列表,它将是(60,0,0)(50,0,1)(40,0,2)(30,0,3)。如果它是从左上到右下的对角线,它将是(60,0,0)(50,1,1)(40,2,2)(30,3,3)

因此,通过这种方式,问题变得更加普遍: 您希望在矩阵中查找通用坐标指定方向的数字列表

一般算法如下所示:

For each configuration
    For each coordinate of the matrix
        For each element in the list and corresponding local coordinate
            Add the local coordinate to the coordinate within the matrix
            If the value at that coordinate in the matrix does not match go to next configuration
    We found a match! Prosperity and happiness!
和往常一样,魔鬼在于细节。具体地说,在本例中,您实际上不希望遍历矩阵的所有坐标。您真正想要的是检查所有坐标,当添加到模式时,将产生匹配的可能性,同时不会超出矩阵。(这样做可以大大减少错误检查的工作量。)

这是一个简单的二维剪裁问题。在配置的相对定位值中查找最低X和Y以及最高X和Y。如果使用基于零索引的矩阵,则希望起始坐标为
-lowX
-lowY
,最大坐标为
matrixMaxX-1-highX
matrixMaxY-1-highY


附加的好处是,您可以添加任何想要的形状,而不仅仅是上/下/左/右/四条对角线。但这取决于你。

虽然这是一个老问题,但我希望我的回答能帮助别人

在做一个tic tac toe项目的时候,我试图概括出一个解决方案,我认为这个方案也能解决你的问题。 这个实现将寻找“线模式”(这意味着它只适用于水平/垂直/对角线上的一系列元素)

function lookForCombinationsOnGrid(grid, ...args) {
/* This function looks for a linear sequence of elements (x, o, undefined) 
on the grid. 
It returns an array of all beginning and ending coordinates (x, y) for 
the corresponding pattern. 
Inputs:
- grid, a system of coordinates with an x-axis and an inverted y-axis.   
- elements can be any sort of built-in objects. 
*/

let sequence = [];
sequence.push(args[0]);
args.reduce(function (accumulator, currentValue, currentIndex, args) {
    return sequence.push(currentValue);
});
console.log("sequence =", sequence);

let testedArr;
// Look for this combination horizontally. 
let result1 = [];
for (i = 0; i < grid.length; i++) {
    for (j = 0; j <= grid[i].length - sequence.length; j++) {
        testedArr = [];
        for (k = 0; k < sequence.length; k++) {
            testedArr.push(grid[i][j + k]);
        }
        if (testedArr.join() === sequence.join()) {
            let start = [j, i];
            let end = [j + sequence.length - 1, i];
            result1.push([start, end]);
        }
    }
}
console.log("Found", result1.length, "results horizontally. ");

// Look for this combination vertically. 
let result2 = [];
for (i = 0; i < grid[0].length; i++) {
    for (j = 0; j <= grid.length - sequence.length; j++) {
        testedArr = [];
        for (k = 0; k < sequence.length; k++) {
            testedArr.push(grid[j + k][i]);
        }
        if (testedArr.join() === sequence.join()) {
            let start = [i, j];
            let end = [i, j + sequence.length - 1];
            result2.push([start, end]);
        }
    }
}
console.log("Found", result2.length, "results vertically. ");

// Look for this combination diagonally. 
let result3 = [];
for (i = 0; i <= grid.length - sequence.length; i++) {
    for (j = 0; j <= grid[i].length - sequence.length; j++) {
        testedArr = [];
        for (k = 0; k < sequence.length; k++) {
            testedArr.push(grid[i + k][j + k]);
        }
        if (testedArr.join() === sequence.join()) {
            let start = [j, i];
            let end = [j + sequence.length - 1, i + sequence.length - 1];
            result3.push([start, end]);
        }
    }
}
console.log("Found", result3.length, "results diagonally (left to right). ");

// and diagonally the other way... 
let result4 = [];
for (i = 0; i <= grid.length - sequence.length; i++) { // line i = 0
    for (j = grid[i].length-1 ; j >= 0 + sequence.length-1; j--) { // column j = 1
        testedArr = [];
        for (k = 0; k < sequence.length; k++) {
            testedArr.push(grid[i + k][j - k]); // + 1 line to i, -1 col to j
        }
        if (testedArr.join() === sequence.join()) {
            let start = [j, i];
            let end = [j - sequence.length + 1, i + sequence.length - 1];
            result4.push([start, end]);
        }
    }
}
console.log("Found", result4.length, "results diagonally (right to left). ");

let result = result1.concat(result2);
result = result.concat(result3);
result = result.concat(result4);

return result;
}
grid = [[1, 1, 3],
        [1, 1, 1],
        [1, 1, 1],
        [0, 1, 1]];
console.log(lookForCombinationsOnGrid(grid, 1, 1, 1, 0 ));
函数lookForCombinationsOnGrid(网格,…args){
/*此函数用于查找元素的线性序列(x,o,未定义)
在网格上。
它返回一个数组,其中包含所有的起始坐标和结束坐标(x,y)
相应的模式。
投入:
-网格,一种坐标系,具有一个x轴和一个倒置的y轴。
-元素可以是任何种类的内置对象。
*/
让序列=[];
sequence.push(args[0]);
args.reduce(函数(累加器、currentValue、currentIndex、args){
返回序列。推送(currentValue);
});
console.log(“sequence=”,sequence);
让测试者;
//在水平方向上查找此组合。
设result1=[];
对于(i=0;i对于(j=0;j,你的问题是…?你的算法必须找到全部吗?还是只有一个?例如:在你的上一个矩阵中,它应该找到全部3吗?每个位置都是相同的数字吗?你永远不需要匹配,例如,[1 2 3]?glowcoder:在我的上一个矩阵中,只有2个相似的模式-左上角1个,最后一行1个序列。丹尼尔,你能用一个例子详细说明你的解决方案吗?我无法理解不同的步幅如何消除4个不同算法的需要一个算法,4个步幅。“矢量化”上面的4 x 5示例,从一开始就扫描第一个匹配的数字,然后依次使用1、3、4和5的步幅检查其余的数字。