【问题标题】:Counting islands in a matrix from file从文件中计算矩阵中的岛屿
【发布时间】:2018-08-27 15:27:05
【问题描述】:

所以我无法解决我的 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;
}

【问题讨论】:

  • 请注意,trailing white space in scanf() formats 通常会引起麻烦。它可能对您的程序无害,但原则上应避免。
  • 我认为你不需要 bfs。也许尝试连接组件的方法。 en.wikipedia.org/wiki/Connected-component_labeling
  • 你需要描述你的代码在做什么,然后也许你会得到一些帮助
  • 从“左上角”开始搜索,依次扫描每一行。当您遇到L 时,您会看到一个岛的最左上角(但该岛的其余部分可能在您开始的位置的左侧,但都在同一条线上或以下)。将L 转换为另一个字符(例如@)。现在四处寻找已连接的L,将每个都转换为@,因为它是当前岛的一部分。当没有更多连接的L 时,从您开始当前岛的位置继续前进,忽略任何@ 标记并寻找下一个L。这样可以避免回溯。
  • 如果有LT 形状的段,我认为问题不是格式正确的;我可以根据策略将 2 或 3 有效分解为矩形的示例。如果我们排除接触矩形,那么它可以通过在地图上进行一次扫描来完成,使用一个模板来查看当前位置、上方的元素和左侧的元素,同时扫描右侧和向下(作为 Jonathan 的简化上面的解决方案)

标签: c breadth-first-search


【解决方案1】:

找到了这个似乎更简单快捷的解决方案

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

【讨论】:

  • 非常好的解决方案,但它不会将L-shape 中的岛屿算作一个岛屿吗?我相信解决方案需要矩形
  • 我觉得应该把&amp;&amp;改成||,或者把边缘岛和其他的分开处理
【解决方案2】:

我将输入一个我想到的非常基本的解决方案。请注意,它肯定不是最优的,并且是一种蛮力方法。

基本上,我的想法是逐个元素遍历矩阵,每次找到 L(岛的开始)时,通过从一个邻居到另一个邻居并用数字标记它来找到它的边界当前岛,直到岛的元素不再有邻居,然后继续遍历矩阵,每次找到未标记的 L 时重复相同的步骤。

【讨论】:

  • Multumesc :)),am inteles pana la urma cum as putea sa o fac si am postat mai jos
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
  • 1970-01-01
相关资源
最近更新 更多