【问题标题】:Checking for same adjacent number in a matrix检查矩阵中的相同相邻数字
【发布时间】:2021-12-18 20:23:36
【问题描述】:

嘿,我正在尝试构建一个函数来检查 N*N 矩阵是否具有至少两个相邻(上下左右)相同的数字(数字从 0 到 h-1),如果有则返回 1 , 如果没有,则为 0。 如果即将到来的元素相同,我想首先检查行,然后沿着列检查。但是我必须小心最后的元素,因为 board[n][j] 或 board[i][n] 不存在。这是我写的,有没有更快的方法来解决这个问题?另外,我的解决方法对吗?

int check (game_t *p){
int i,j;
for (i=0;i<p->n;i++){
      for (j=0;j<p->n-1;j++){
               if(p->board[i][j]==p->board[i][j+1]) return 1;}}
for (j=0;j<p->n;j++){
      for (i=0;i<p->n-1;i++){
               if(p->board[i][j]==p->board[i+1][j]) return 1;}}
return 0;
}

结构游戏定义:

typedef struct game {
int h;
int n;
int ** board;
} game_t;

【问题讨论】:

  • 您是在问我们您的作业是否正确?测试时会发生什么?
  • 它似乎可行,但我不确定我的程序是否涵盖所有可能性以及它是否是解决问题的最佳方法。
  • 它返回正确的答案,但可能不是最聪明的方法。
  • p-&gt;board[0][0]的类型是什么?我猜int?您能否编辑您的问题并发布game_t 的定义?有了这些信息,代码可能会被简化并变得更快。

标签: arrays c algorithm matrix


【解决方案1】:

稍作重组。我们可以将行邻接测试和列邻接测试组合成一个循环。

检查给定行时,我们可以与该行的前一个值进行比较。但是,我们也可以将值与下一行中它下面的值进行检查。

我们可以在行值的单个循环中执行此操作。所以,我们只需要一个 套嵌套的for 循环而不是两个。

我们在末尾添加一个特殊的循环来检查最后一行[没有检查下一行]。

此外,通过添加一些额外的int * 指针来指向要比较的行,我们可以简化board 矩阵索引并消除一些重复的额外指针/值提取。

这是重构的代码。有注释:

typedef struct game {
    int h;
    int n;
    int **board;
} game_t;

int
check(game_t *p)
{
    int n = p->n;
    int nm1 = n - 1;
    int yidx;
    int xidx;
    int xcur;
    int xprev;
    int *rowtop;
    int *rowbot;

    // check most rows
    yidx = 0;
    for (;  yidx < nm1;  ++yidx) {
        // point to current row of board
        rowtop = p->board[yidx];

        // point to next row of board
        rowbot = p->board[yidx + 1];

        // get the "previous" value in the current row
        xprev = rowtop[0];

        // check all values in given row
        for (xidx = 1;  xidx < n;  ++xidx, xprev = xcur) {
            // get current value
            xcur = rowtop[xidx];

            // does it match the previous value in the row?
            if (xcur == xprev)
                return 1;

            // check current value against value just below it in the next row
            if (xcur == rowbot[xidx])
                return 1;
        }
    }

    // check last row
    rowtop = p->board[yidx];
    xprev = rowtop[0];
    for (xidx = 1;  xidx < n;  ++xidx, xprev = xcur) {
        xcur = rowtop[xidx];
        if (xcur == xprev)
            return 1;
    }

    return 0;
}

更新:

上述方法会起作用并且相当很快。

但是,在速度方面“疯了”,所以,次要调整以最小化内存获取[稍微]:

typedef struct game {
    int h;
    int n;
    int **board;
} game_t;

int
check(game_t *p)
{
    int n = p->n;
    int yidx;
    int xidx;
    int xcur;
    int xprev;
    const int *rowtop;
    const int *rowbot;

    // check most rows
    rowtop = p->board[0];
    for (yidx = 1;  yidx < n;  ++yidx, rowtop = rowbot) {
        // point to next row of board
        rowbot = p->board[yidx];

        // get the "previous" value in the current row
        xprev = rowtop[0];

        // check all values in given row
        for (xidx = 1;  xidx < n;  ++xidx, xprev = xcur) {
            // get current value
            xcur = rowtop[xidx];

            // does it match the previous value in the row?
            if (xcur == xprev)
                return 1;

            // check current value against value just below it in the next row
            if (xcur == rowbot[xidx])
                return 1;
        }
    }

    // check last row
    xprev = rowtop[0];
    for (xidx = 1;  xidx < n;  ++xidx, xprev = xcur) {
        xcur = rowtop[xidx];
        if (xcur == xprev)
            return 1;
    }

    return 0;
}

【讨论】:

  • 谢谢!它工作得很好。
  • 不客气!这很容易,因为您的代码是完整的并且解释很清楚。请考虑支持并接受我的回答。见:stackoverflow.com/help/someone-answers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多