2次元配列の接続のチェック

だから私は正方形の2次元アレイを持っています。寸法はnxnになります。配列には0と1だけが含まれます。より具体的には、正確にn 1を含む。すべての1が空間的に「接続」されているかどうかを確認する必要があります。例:

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

これは無効です。対角線接続はカウントされません。これまでのところ、私のコードは配列をチェックしますが、唯一の1のものだけをチェックします。たとえば、1が2つの2つのグループに分割されている場合、私の小切手はそれを逃してしまうでしょう。アドバイスをいただければ幸いです。 これまでのところ私のコードです:

    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

}

2
あなたはどうやって始めることができると思いますか?
追加された 著者 Aurelio De Rosa,
場所(x、y)にいるとします。これをC配列の座標にどのように変換しますか?表記法を翻訳したので、現在の場所の隣に 1 があるかどうかをどのように判断しますか?最後に、隣接する 1 のシーケンスをどのように追跡しますか?
追加された 著者 ObscureRobot,

2 答え

いくつかのアドバイス:

  • 最初の1つを見つけたら、良い隣人(それも1です)をリストに入れておくことができます。そのようなものを訪問することができます(ああ、それはCだし、便利なリストはありません。 n サイズの配列)、そうでなければ再帰を使うことができます(実際には使いにくく面白いでしょう)
  • あなたは n 1sがあることを知っています。これは、同じグループ内の残りの n-1 を見つける必要があることを意味します。 n より小さいと判断した場合はfalseを返すことができます。
  • 方向をマージするには、オフセットを使用します(例: int dirs [4] [2] = {{1,0}、{ - 1,0}、{0,1}、{0、-1}} あなたは方向をループすることができます

私はあなたに疑似コードを提供することができますが、それは不正行為になるでしょう、あなたが知っている..

再帰のために、 n-1 サイズのグループに1つの1が接続されている場合、 nサイズの 1のグループが接続されます。それはあなたに正しい方向を指すはずです。

1
追加された
グローバル変数(evil)またはポインタを使用して
追加された 著者 Jack,
これはもちろんポインターですが、配列として宣言されています。いくつかの技術的な違いがありますが、ポインタとして使用できます。
追加された 著者 Jack,
再帰を使用するには、関数を使って実際の配列をどうやって渡すのですか?
追加された 著者 Free_D,
それ自身のポインタにarray2dですか?または新しいポインタをmallocする必要がありますか?
追加された 著者 Free_D,

'1' の位置を配列に保存するために、4つの別々の二次元変数を追跡する配列から始めます。これにより、検証が非常に簡単になります。

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;
}

次に、配置されたインスタンスの配列をループしてインデックスオフセットをチェックし、それらがすべて隣接していることを確認します。隣接していないインデックスが見つかるとすぐに失敗します。次の例では、この時点で4になるはずなので、 count 変数を使用しています。すべてがカバーされている限り、逆順でインスタンスをトラバースするかどうかは問題になりません。さらに、素晴らしいコード再利用です(:

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 == 1 のときに0オフセットがチェックされているため、 count == 0 を使用してループを実行する必要はありません。最後に、PCがループを通過して失敗する場合、 '1' のインスタンスが4つ見つかり、すべてが隣接していることがわかります。成功:

return true;
0
追加された