LINUX.ORG.RU

Пожалуйста помогите найти ошибки (небольшой код на perl'e)...?


0

1

Почему-то когда ввожу это:
101
000
101
прога выдаёт «3» и при др. случаях тоже иногда выдаёт неправильный результат. Почему? Помогите пожалуйста, а то над прогой уже несколько дней сижу!

Условия задачи: Каждый элемент квадратной матрицы размеренности N x N равен нулю, либо единице. Найдите количество «островов», образованных единицами. Под «островом» понимается группа единиц (либо одна единица), со всех сторон окруженная нулями (или краями матрицы). Единицы относятся к одному «острову», если из одной из них можно перейти к другой «наступая» на единицы, расположенные в соседних клетках. Соседними являются клетки, граничащие по горизонтали или вертикали.

#!/usr/bin/perl
sub zero;
@sea = map{[split//]}<>; # ввод и создание двумерного массива
$count = 0;
for $y(0..$#sea){ # обход всех элементов
  for $x(0..$#{$sea[$y]}){
    if($sea[$y]->[$x] eq "1"){ # если найдена "1", то обнулить весь отсров
      $count++;
      zero $x, $y, \@sea;
    }
  }
}
print "$count\n";

sub zero{ # рекурсивное обнуление строва
  my $x = $_[0], $y = $_[1], $sea = $_[2];
  if(!$sea->[$y][$x] || $x < 0 || $y < 0 || $y > $#{$sea} || $x > $#{$sea->[$y]}){
    return;
  }
  $sea->[$y][$x] = 0;
  zero $x+1, $y, $sea;
  zero $x-1, $y, $sea;
  zero $x, $y+1, $sea;
  zero $x, $y-1, $sea;
}

P.S. И вообще хотелось бы услышать как можно улучшить (упростить) код.


Первое что бросается в глаза - отсутствие use strict;

router ★★★★★
()

Найдите количество «островов»

«Связные области» ;)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void
zero(int **z, int m, int n, int i, int k)
{
  z[i][k] = 0;

  /* with tail calls */
  if ((i > 0) && (z[i-1][k] == 1))
    zero(z, m, n, i-1, k);
  if ((i < m-1) && (z[i+1][k] == 1))
    zero(z, m, n, i+1, k);
  if ((k > 0) && (z[i][k-1] == 1))
    zero(z, m, n, i, k-1);
  if ((k < n-1) && (z[i][k+1] == 1))
    zero(z, m, n, i, k+1);
}

int
count(int **z, int m, int n)
{
  int i, k, r = 0;
  
  for(i = 0; i < m; i++)
    for(k = 0; k < n; k++)
      if (z[i][k] == 1) {
        r++;
        zero(z, m, n, i, k);
      }
  
  return r;
}

int
main ()
{
  int **z = calloc(3, sizeof(int*));
  z[0]    = calloc(3, sizeof(int));
  z[1]    = calloc(3, sizeof(int));
  z[2]    = calloc(3, sizeof(int));
  z[0][0] = z[0][2] = z[2][1] = z[2][2] = 1;
  
  printf("%i\n", count(z, 3, 3));
  
  return 0;
}

У вас zero другая - вы сначала проверяете индексы, потом делаете рекурсивные вызовы. Наверно, в этом проблема.

quasimoto ★★★★
()

У тебя в массив попадают символы перевода строки, появляется фантомный N+1 элемент в строке, он всё портит.

gman
()
for $y(0..$#sea){ # обход всех элементов

Баг подсветки

Bad_ptr ★★★★★
()
Ответ на: комментарий от gman

Спасибо!

Спасибо огромное, а то уже замучался над этой прогой сидеть! фуууххх...

mencey
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.