C 从文件中计算矩阵中的孤岛

C 从文件中计算矩阵中的孤岛,c,breadth-first-search,C,Breadth First Search,所以我在为我的IT考试解决一个问题时遇到了困难。 我解决了它,它部分工作,但我可以找到一个解决方案,只使用BFS,我相信这不需要图遍历算法,因为我们还没有做过,但我找不到任何其他解决方案。有人能给我一个提示吗?我会把BFS代码贴在下面,告诉你我是如何解决这个问题的,而不是我认为应该如何解决这个问题的 #include <stdio.h> #include <stdlib.h> char file[20][20]; int v[20], ns, n, comp, c[20

所以我在为我的IT考试解决一个问题时遇到了困难。

我解决了它,它部分工作,但我可以找到一个解决方案,只使用BFS,我相信这不需要图遍历算法,因为我们还没有做过,但我找不到任何其他解决方案。有人能给我一个提示吗?我会把BFS代码贴在下面,告诉你我是如何解决这个问题的,而不是我认为应该如何解决这个问题的

#include <stdio.h>
#include <stdlib.h>
char file[20][20];
int v[20], ns, n, comp, c[20];
int prim;
int ultim;
FILE *f;
int nr = 0, nl, nc;

void matrix() {
  int i, j;
  char c, n;
  fscanf(f, "%d %d \n", &nl, &nc);
  for (i = 1; i <= nl; i++) {
    for (j = 1; j <= nc; j++) {
      c = getc(f);
      file[i][j] = c;
    }
    n = getc(f);
  }
}
// citirea grafului din fisier text si construirea matricei de adiacenta

// afisarea pe ecran a matricei de adiacenta

void afisare() {
  int i, j;
  printf("Matricea  : \n");

  for (i = 1; i <= nl; i++)

  {
    for (j = 1; j <= nc; j++)

      printf("%c", file[i][j]);

    printf("\n");
  }
}

// returnează primului nod nevizitat

int exista_nod_nevizitat(int v[20], int n) {
  int i, j;
  for (i = 1; i <= nl; i++)

    if (v[i] == 0)

      return i; // primul nod nevizitat

  return 0; // nu mai exista noduri nevizitate
}

// parcurgerea în latime a unei componente conexe, plecând din nodul de start ns

void parcurgere_latime(char file[20][20], int nl, int ns) {
  int i, j;
  comp++;

  v[ns] = 1;

  prim = ultim = 1;

  c[ultim] = ns;

  while (prim <= ultim) {
    for (i = 1; i <= nl; i++)

      if (file[c[prim]][i] == 'L')

        if (v[i] == 0)

        {
          ultim++;

          c[ultim] = i;

          v[i] = 1;
        }

    prim++;
  }
}

// functia principala main()

int main() {
  int set, nr;
  f = fopen("in1.txt", "r");

  fscanf(f, "%d \n", &set);
  while (set != 0) {
    matrix();
    afisare();

    while (exista_nod_nevizitat(v, n) != 0) {
      ns = exista_nod_nevizitat(v, n);

      parcurgere_latime(file, n, ns); // parcurg o alta componenta conexa
    }

    printf("Graful este alcătuit din ");
    printf("%d", comp);
    printf("componente conexe \n");

    set--;
  }
  return 0;
}
#包括
#包括
字符文件[20][20];
INTV[20],ns,n,comp,c[20];
int-prim;
综合性;
文件*f;
int nr=0,nl,nc;
空隙矩阵(){
int i,j;
字符c,n;
fscanf(f、%d%d\n、&nl、&nc);

对于(i=1;i我将键入一个我想到的非常基本的解决方案。请注意,它不一定是最优的,而且有点像蛮力方法


基本上,我想的是逐元素遍历矩阵元素,每次你找到一个L(岛的开始),通过从一个邻居到另一个邻居并用当前岛的编号将其标记下来,直到岛上的元素没有更多的邻居,然后继续遍历矩阵,每次找到未标记的L时重复相同的步骤。

我将键入一个非常基本的解决方案请注意,这肯定不是最优的,而且是一种蛮力方法


基本上,我想的是逐元素遍历矩阵元素,每次你找到一个L(岛的开始),通过从一个邻居到另一个邻居并用当前岛的编号将其标记下来,直到岛上的元素没有更多的邻居,然后继续遍历矩阵,每次找到未标记的L时重复相同的步骤。

找到了这个解决方案,它似乎更容易,f紫菀

int countIslands(char a[100][100])
{
    int count = 0;
    for ( i=0; i<nl; i++)
    {
        for (j=0; j<nc; j++)
        {
            if (a[i][j] == 'L')
            {
                if ((i == 0 || a[i-1][j] == '.') &&
                    (j == 0 || a[i][j-1] == '.'))
                    count++;
            }
        }
    }

    return count;
}
int countIslands(字符a[100][100])
{
整数计数=0;

对于(i=0;i发现这个解决方案似乎更简单、更快

int countIslands(char a[100][100])
{
    int count = 0;
    for ( i=0; i<nl; i++)
    {
        for (j=0; j<nc; j++)
        {
            if (a[i][j] == 'L')
            {
                if ((i == 0 || a[i-1][j] == '.') &&
                    (j == 0 || a[i][j-1] == '.'))
                    count++;
            }
        }
    }

    return count;
}
int countIslands(字符a[100][100])
{
整数计数=0;

对于(i=0;iNote通常会导致问题。它可能对程序无害,但原则上应该避免。我认为您不需要bfs。也许可以尝试使用连接组件的方法。您需要描述代码正在执行的操作,然后可能会收到一些帮助搜索,从“左上角”开始,依次扫描每一行。当你遇到一个
L
时,你得到了一个岛的最左上角(但岛的其余部分可能在你开始的地方的左边,但都在同一行或下面)。将
L
转换为另一个字符(
@
)。现在四处寻找已连接的
L
,将每个标记转换为
@
,因为它是当前孤岛的一部分。如果没有更多已连接的
L
,请从当前孤岛的起始位置向前移动,忽略任何
@
标记,然后查找下一个
L
。这样可以避免回溯。我不认为如果有
L
T
形状的段,问题就形成了;我可以举例说明,根据策略,2或3是有效的矩形分解。如果我们排除了接触矩形,那么可以通过对地图进行单次扫描,使用一个模板查看cur位置,即地图上方的元素d左右扫描时左边的一个(作为上述Jonathan解决方案的简化)请注意,这通常会造成麻烦。这可能对您的程序无害,但原则上应该避免。我认为您不需要bfs。也许可以尝试连接组件的方法。您需要描述您的代码正在执行的操作,然后您可能会收到一些帮助搜索,从左上角开始,依次扫描每一行。当您遇到一个
L
,你已经得到了一个岛的最左上角(但岛的其余部分可能在你开始的地方的左边,但都在同一行或下面)。将
L
转换为另一个字符(
@
)。现在四处寻找已连接的
L
,将每个标记转换为
@
,因为它是当前孤岛的一部分。如果没有更多已连接的
L
,请从当前孤岛的起始位置向前移动,忽略任何
@
标记,然后查找下一个
L
。这样可以避免回溯。我不认为如果有
L
T
形状的段,问题就形成了;我可以举例说明,根据策略,2或3是有效的矩形分解。如果我们排除了接触矩形,那么可以通过对地图进行单次扫描,使用一个模板查看cur位置,即地图上方的元素d左右扫描时左边的一个(作为上述乔纳森解决方案的简化)Multumesc:),我是inteles pana la urma cum,我是putea sa o fac si am postat mai josMultumesc:),作为putea sa o fac si am postat mai Jos非常好的解决方案,但它不会将
L形的岛屿作为一个岛屿计算吗?我认为解决方案需要矩形。我认为
&
应该更改为
|
,或者将边缘岛屿与REST非常好的解决方案分开处理,但是它不会将
L形的孤岛计算为一个孤岛吗?我认为解决方案需要矩形。我认为
&&
应该更改为
|
,或者将边缘孤岛与其他孤岛分开处理