对角线、垂直线和水平线搜索矩阵形成一个点

Posted

技术标签:

【中文标题】对角线、垂直线和水平线搜索矩阵形成一个点【英文标题】:Searching a Matrix Diagonally, Vertically and Horizontally form a point 【发布时间】:2017-01-23 20:17:47 【问题描述】:

我正在寻找一种有效的算法,它从给定索引的点对角、垂直和水平遍历 N x N 方阵。

例如,在一个 4x4 矩阵中,如果[2][1] 是给定的索引,算法应该通过索引搜索另一个给定元素的存在:

[0][1], [1][1], [3][1], // Vertically
[2][0], [2][2], [2][3], // Horizontally
[3][0], [1][2], [0][3], // Diagonally (/)
[1][0], [3][2]          // Diagonally (\)

这张照片会更清楚:

注意给定的索引 ([2][1])不包括在搜索中。


我设法用 C++ 编写了一个效率不高的可行解决方案:

int Check(int arr[][100], int i, int j, int q, int n)

    for (int k = 0; k < n; k++)
        if ((arr[i][k] == q && k != j) || (arr[k][j] == q && k != i))
            return 1;
    //vertical n horizontal

    if ((i - j) >= 0)
    
        for (int l = i - j, m = 0; l < n; l++)
            if (arr[l][m++] == q && l != i && (m - 1) != j)
                return 1;
    
    else
    
        for (int l = j - i, m = 0; l < n; l++)
            if (arr[m++][l] == q && (m - 1) != i&&l != j)
                return 1;
    
    //  Diagonal (\)

    int l = i, m = j;
    while (1)
    
        if (l == 0 || m == n - 1)
            break;
        l--;
        m++;
    

    if (l == 0)
    
        while (m >= 0)
            if (arr[l++][m--] == q && (l - 1) != i && (m + 1) != j)
                return 1;
    
    else
    
        while (l < n)
            if (arr[l++][m--] == q && (l - 1) != i && (m + 1) != j)
                return 1;
    
    //  Diagonal(/)

    return -1;

Check() 从元素arr[i][j] 中搜索矩阵arr 对角线、垂直线和水平线。如果q 存在于任一方向,则返回1,否则返回-1。

如何有效地实现上述内容?

任何代码(最好是 C/C++)都会很棒。

【问题讨论】:

【参考方案1】:

您必须简化循环内操作,排除对当前单元格的过多检查。只是在当前单元格之前和之后单独行走。

 //horizontal
 for (int k = 0; k < j; k++)
       if (arr[i][k] == q)
           return 1;
 for (int k = j+1; k < n; k++)
       if (arr[i][k] == q)
           return 1;

//main diagonal, case of bottom-left triangle
 dij = i-j;
 if (dij>=0) 
    for (k=0;k<j;k++)
       if (arr[k+dij][k] == q)
           return 1;
    for (k=i+1;k<n;k++)
       if (arr[k][k-dij] == q)
           return 1;

【讨论】:

您的代码不适用于垂直和其他对角线(主对角线除外..不确定它的名称)。您也没有从搜索中排除给定的i,j。另外,在第二个循环中,为什​​么要k = j+1? (你检查的是垂直的吗?) 垂直和其他对角线我没有写代码,可能是类比写的。我确实排除了 (i,j)。 k = j+1 从右侧单元格开始 是的..你是对的,它确实排除了。但是..我尝试将该循环分成垂直和水平的 4 个循环,看起来单个循环稍微快一些.. 有可能。现代处理器有时比较长的简单循环更快地执行具有较小循环计数的复杂循环。这些操作的时间对您的程序如此重要吗?对于任何合理的矩阵大小,这些搜索都应该很快...... 实际上,是的。该程序是为N Queens problem 寻找解决方案,如果您熟悉的话。它可以工作,但需要 30 多秒才能生成大于 10 的电路板尺寸的解决方案。Here's我的代码,如果你有兴趣。

以上是关于对角线、垂直线和水平线搜索矩阵形成一个点的主要内容,如果未能解决你的问题,请参考以下文章

查找是不是存在于 2D 中对角线、水平线或垂直线 - 一个接一个的值

防止与新路径发生碰撞

华为机试真题 C++ 实现学生方阵

从嵌套列表的子数组返回元素的索引

iOS - 检查[CGPoint]直线

华为OD机试真题 Python 实现学生方阵