检查二维阵列中的连接

时间:2011-10-28 03:03:59

标签: c

所以我有一个方形的2d数组。尺寸将为nxn。该数组仅包含0和1。更具体地说,它将包含n 1。我需要检查所有1是否在空间上“连接”。示例:

    0 0 0 0
    1 1 1 0
    0 0 0 1
    0 0 0 0

这是无效的。对角线连接不计算在内。到目前为止,我的代码将检查数组,但仅限于单个1。例如,如果将1分为两组,则我的检查会错过它。任何建议表示赞赏。 到目前为止,这是我的代码:

    int conected(char *stringptr) 
    {
int n=sqrt(strlen(stringptr));
int i=0;
int j=0;
int k=0;
char array2d[n][n];

for (j=0;j<n;j++) {
    for (i=0;i<n;i++) {
        array2d[j][i]=stringptr[k];
        k++;
    }
}

for (j=0;j<n;j++) {
    for (i=0;i<n;i++) {
        if (array2d[j][i]=='1') {
            if (i==0 && j==0) {//special case for first element
                if ((array2d[j][i+1]=='0') && (array2d[j+1][i]=='0')) {
                    return 0;
                }
            }
            else if ((j==0) && (i!=(n-1))) {//top row
                if ((array2d[j][i+1]=='0') && (array2d[j+1][i]=='0') && (array2d[j][i-1]=='0')) {
                    return 0;
                }
            }
            else if ((j==0) && (i==(n-1))) {// right corner
                if ((array2d[j+1][i]=='0') && (array2d[j][i-1]=='0')) {
                    return 0;
                }
            }
            else if ((i==0) && (j!=(n-1))) { //left column
                 if ((array2d[j][i+1]=='0') && (array2d[j+1][i]=='0') && (array2d[j-1][i]=='0')) {
                    return 0;
                }
            }
            else if ((i==(n-1)) && (j!=(n-1))) {// right column
                if ((array2d[j][i-1]=='0') && (array2d[j+1][i]=='0') && (array2d[j-1][i]=='0')) {
                    return 0;
                }
            }
            else if ((i==0) && (j==(n-1))) {//bottom left corner
                if ((array2d[j][i+1]=='0') && (array2d[j-1][i]=='0')) {
                    return 0;
                }
            }
            else if ((j==(n-1)) && (i!=(n-1))) {//bottom row
                if ((array2d[j][i+1]=='0') && (array2d[j-1][i]=='0') && (array2d[j][i-1]=='0')) {
                    return 0;
                }
            }
            else if ((j==(n-1)) && (i==(n-1))){ //bottom right corner
                if ((array2d[j][i-1]=='0') && (array2d[j-1][i]=='0')) {
                    return 0;
                }
            }
            else {
                if ((array2d[j][i-1]=='0') && (array2d[j+1][i]=='0') && (array2d[j-1][i]=='0') && (array2d[j][i+1]=='0')) {
                    return 0;
                }
            }
        }
    }
}   
return 1;

}

2 个答案:

答案 0 :(得分:1)

一些建议:

  • 一旦你找到第一个你可以在一个列表中存储好邻居(也是1),这样你就可以访问那些(哦,它是C,你没有方便的列表,只需使用一个 n 大小的数组),否则你可以使用递归(实际使用它会很棘手和有趣)
  • 你知道有 n 1s,这意味着一旦你找到了一个,你必须在同一个组中找到剩余的 n-1 :如果是你发现它比 n 小,那么你可以返回false
  • 您可以使用偏移量合并路线(例如 int dirs[4][2] = {{1,0},{-1,0},{0,1},{0,-1}},这样会更优雅,更不容易出错,您可以循环方向

我可以为你提供伪代码,但它会作弊,你知道......

仅出于递归的目的:如果一个1连接到 n-1 大小的组,则连接 n大小的组1s。这应该指向正确的方向。

答案 1 :(得分:0)

从数组开始,跟踪四个独立的二维变量,以保存数组中'1'的位置。这将使验证变得非常简单:

int coords[4][2] = {0};

您还需要一个计数器,以确保只找到'1'的4个坐标:

int count = 0;

我还建议为可读性定义一些常量:

const int X = 0;
const int Y = 1;

然后遍历您的数组以查找'1'的所有实例。如果count超过4,或者小于4,则失败。

for ( int x = 0; x < 4; x++ )
{
  for ( int y = 0; y < 4; y++ )
  {
    if ( array2d[x][y] == '1' )
    {
      if ( count < 4 ) // Make sure the 4 instances have not yet been found.
      {
        // Save the instance.
        coords[count][X] = x;
        coords[count][Y] = y;
      }

      if ( ++count > 4 ) // Increments count and then checks if greater than 4.
      {
        return false;
      }
    }
  }
}

if ( count != 4 )
{
  return false;
}

接下来,遍历查找索引偏移量的已定位实例数组,以验证它们是否全部相邻。一旦找到不相邻的索引,就会失败。下面的例子使用我们的count变量,因为此时它应该是4,如果我们以相反的顺序遍历实例并不重要,只要它们全部被覆盖。此外,这是很好的代码重用。 (:

int x1, y1, x2, y2;

do
{
  count--; // decrement count so index offset is valid
  x1 = coords[count][X];
  y1 = coords[count][Y];
  x2 = coords[count-1][X];
  y2 = coords[count-1][Y];

  // Check for fail condition . . .
  if ( (abs(x1 - x2) != 1) && (abs(y1 - y2) != 1) )
  {
    // Both the X and Y coordinates of the two instances,
    // which should be adjacent, are greater than 1; fail.
    return false;
  }
}
while ( count > 0 );
// Each time through loop count will equal 3, 2, 1, and then exit.

在上面的示例中,我们不希望使用count == 0遍历循环,因为在count==1时检查了0偏移量。最后,如果PC通过循环而没有失败,我们知道确实发现了'1'的4个实例并且它们都是相邻的;成功:

return true;