Функции, принимать до 27 параметров, который проверяет существование пути в графе


Там должен быть лучший способ, чем этот, который сохраняет логику пока щадящ мне множество линий:

sub has_path {
  clearerr;
  my %Graph = gref(shift);
  my $A = shift;
  my $B = shift;
  my $C = shift;
  my $D = shift;
  my $E = shift;
  my $F = shift;
  my $G = shift;
  my $H = shift;
  my $I = shift;
  my $J = shift;
  my $K = shift;
  my $L = shift;
  my $M = shift;
  my $N = shift;
  my $O = shift;
  my $P = shift;
  my $Q = shift;
  my $R = shift;
  my $S = shift;
  my $T = shift;
  my $U = shift;
  my $V = shift;
  my $W = shift;
  my $X = shift;
  my $Y = shift;
  my $Z = shift;
  # returns VT_BOOL
  my $bool = 0;
  my $switcher = dectab( [ $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z ] );
  given ($switcher) {
   when ( "--------------------------" ) {
    seterr( "No path." );
    } # no path
   when ( "X-------------------------" ) {
    seterr( "Path of one element." );
    } # path of 1 element
   when ( "XX------------------------" ) {
    $bool = $Graph->has_path( $A,  $B );
   }
   when ( "XXX-----------------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C );
   }
   when ( "XXXX----------------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D );
   }
   when ( "XXXXX---------------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E );
   }
   when ( "XXXXXX--------------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F );
   }
   when ( "XXXXXXX-------------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G );
   }
   when ( "XXXXXXXX------------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H );
   }
   when ( "XXXXXXXXX-----------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I );
   }
   when ( "XXXXXXXXXX----------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J );
   }
   when ( "XXXXXXXXXXX---------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K );
   }
   when ( "XXXXXXXXXXXX--------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L );
   }
   when ( "XXXXXXXXXXXXX-------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M );
   }
   when ( "XXXXXXXXXXXXXX------------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N );
   }
   when ( "XXXXXXXXXXXXXXX-----------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O );
   }
   when ( "XXXXXXXXXXXXXXXX----------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P );
   }
   when ( "XXXXXXXXXXXXXXXXX---------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q );
   }
   when ( "XXXXXXXXXXXXXXXXXX--------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R );
   }
   when ( "XXXXXXXXXXXXXXXXXXX-------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S );
   }
   when ( "XXXXXXXXXXXXXXXXXXXX------" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T);
   }
   when ( "XXXXXXXXXXXXXXXXXXXXX-----" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U );
   }
   when ( "XXXXXXXXXXXXXXXXXXXXXX----" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V );
   }
   when ( "XXXXXXXXXXXXXXXXXXXXXXX---" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W );
   }
   when ( "XXXXXXXXXXXXXXXXXXXXXXXX--" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X );
   }
   when ( "XXXXXXXXXXXXXXXXXXXXXXXXX-" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y,);
   } 
   when ( "XXXXXXXXXXXXXXXXXXXXXXXXXX" ) {
    $bool = $Graph->has_path( $A,  $B, $C, $D, $E, $F, $G, $H, $I, $J, $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z );
   }
  }  
  return $bool;
 }

Это dectab (таблица решений) суб относится к:

 sub dectab {
  my($ref)=shift;
  my ($res);
  foreach my $key( @$ref){ 
   if ( ! defined $key ) { 
    $res .= '-';
   } else {
    $res .= "X";
   }
  }
  return $res;
 }

clearerr, seterr, и Греф:

sub clearerr {
    $ERRORFLAGGED = 0;
    $ERRORTEXT = "";
}

sub seterr {
    $ERRORTEXT = shift;
    $ERRORFLAGGED = 1;
}

sub gref {
    my $gref = shift;
    if ( defined $grefs->{$gref} ) {
        return $grefs->{$gref};
    } else {
        return undef;
    }
}

Все это является частью гораздо большего обтекания модуль график. Это превращается в DLL-библиотеки com, используя PerlCtrl Активностити по.

Звоню в суб будет сделано, в VBScript (например), по

set o = CreateObject("Wrapper.Graph.2")
...
if o.has_path( "tom", "dick", "harry" ) then 
...

График.ПМ, кстати, определяет has_path как

has_path

   $g->has_path($a, $b, $c, ..., $x, $y, $z)

Return true if the graph has all the edges $a-$b, $b-$c, ..., $x-$y, $y-$z, false otherwise.


547
9
задан 31 января 2011 в 04:01 Источник Поделиться
Комментарии
2 ответа

Как я отметил в комментарии, я думаю, что решение заключается в использовании массивов и срезов. Может быть, вот так:

sub has_path {
clearerr;
my %Graph = gref(shift);
my(@States) = @_;
my $bool = 0;
my $switcher = dectab( [ @States ] );
$switcher =~ m/^(X*)(?:-*)$/;
my $number = length($1);
if ($number == 0) {
seterr( "No path." );
}
else
{
$bool = $Graph->has_path( $States[0 .. ($length - 1)] );
}

return $bool;
}

sub dectab {
my($ref)=shift;
my ($res); foreach my $key( @$ref){
if ( ! defined $key ) {
$res .= '-';
} else {
$res .= "X";
}
}
return $res;
}

Ключевые замечания:


  1. Список письмо переменные лучше рассматривать как массив - я использовал @государств.

  2. Выход из dectab() (который является неизменным), состоит из некоторого количества х, за которым следует некоторое количество черточек. Регулярное выражение матч определяет, сколько крестиков путем изолирования их в строку, $1, и затем вычисляя длину строки. Обратите внимание, что код не проверяет, что выход из dectab соответствует этому шаблону - это, наверное, должно.

  3. Огромный оператор switch суммы поставки элементов 0..(Н-1) на $график->has_path() функция, так что код проходит соответствующие ломтик @государств функции.

Есть еще некоторые биты я не понятно в коде. В частности, я не уверен, о роли (или источников) функций:


  • clearerr

  • Греф

  • seterr

Из-за этого я не могу проверить свою гипотезу. Однако, я думаю, что это решение масштабируется до 200 наименований более легко, чем оригинал - и без необходимости:

use feature "switch";

Больше времени потратил, чтобы код по-прежнему может быть прибрано, я уверен. И, поскольку это Perl, TMTOWTDI - есть более чем один способ сделать это.


Предложение:


  • Предоставить код, который можно скомпилировать и запустить при любой возможности - вы получите лучший код комментарии таким образом.

10
ответ дан 31 января 2011 в 07:01 Источник Поделиться

Хорошо:

В первой строке может быть записано в таком виде:

sub has_path
{
clearerr;
my %Graph = gref(shift);

my ($A, $B, $C, $D, $E, $F
,$G, $H, $I, $J, $K, $L
,$M, $N, $O, $P, $Q, $R
,$S, $T, $U, $V, $W, $X
,$Y, $Z) = @_;

Но если все, что вы делаете это, используя параметры для вызова другой функции, то просто оставьте их в массив @_ , и передать его в функцию вызова:

sub has_path
{
clearerr;
my %Graph = gref(shift);

my $switcher = dectab( @_ ); # just use the input array (- graph)
# as a parameter into dectab.
# If you actually want to limit it then
# splice() off then end.

if ($switcher =~ /^(X+)(-*)$/) # make sure the result is XXX----
{
my $size = length($1); # Count the X.
# Note this block is not entered if
# zero X's in switcher variable

# Cut the $size elements from the input array
# and pass them as parameters to has_path()
return $Graph->has_path(splice(@_, 0 , $size));
}
# If we reach here the call failed.
# Just return the 0
return 0;
}

8
ответ дан 31 января 2011 в 09:01 Источник Поделиться