Próbuję przekonwertować oparte na wyrażeniach regularnych rozwiązanie problemu plecaka z Perla na raku. Szczegóły dotyczące Perlmonks
Rozwiązanie Perl tworzy to wyrażenie regularne:
(?<P>(?:vvvvvvvvvv)?)
(?<B>(?:vv)?)
(?<Y>(?:vvvv)?)
(?<G>(?:vv)?)
(?<R>(?:v)?)
0
(?=
(?(?{ $1 })wwww|)
(?(?{ $2 })w|)
(?(?{ $3 })wwwwwwwwwwww|)
(?(?{ $4 })ww|)
(?(?{ $5 })w|)
)
co się dopasowuje vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww
. Następnie skrót dopasowania %+
zawiera elementy do włożenia do worka.
Moja konwersja raku to:
$<B> = [ [ vv ]? ]
$<P> = [ [ vvvvvvvvvv ]? ]
$<R> = [ [ v ]? ]
$<Y> = [ [ vvvv ]? ]
$<G> = [ [ vv ]? ]
0
<?before
[ { say "B"; say $/<B>; say $0; say $1; $1 } w || { "" } ]
[ { say "P"; say $/<P>; say $0; say $1; $2 } wwww || { "" } ]
[ { say "R"; say $/<R>; say $0; say $1; $3 } w || { "" } ]
[ { say "Y"; say $/<Y>; say $0; say $1; $4 } wwwwwwwwwwww || { "" } ]
[ { say "G"; say $/<G>; say $0; say $1; $5 } ww || { "" } ]
który również pasuje vvvvvvvvvvvvvvvvvvv0wwwwwwwwwwwwwww
. Ale obiekt dopasowania $/
nie zawiera niczego użytecznego. Ponadto wszystkie moje debugowania say
mówią zero, więc w tym momencie wydaje się, że odniesienie wsteczne nie działa?
Oto mój skrypt testowy:
my $max-weight = 15;
my %items =
'R' => { w => 1, v => 1 },
'B' => { w => 1, v => 2 },
'G' => { w => 2, v => 2 },
'Y' => { w => 12, v => 4 },
'P' => { w => 4, v => 10 }
;
my $str = 'v' x %items.map(*.value<v>).sum ~
'0' ~
'w' x $max-weight;
say $str;
my $i = 0;
my $left = my $right = '';
for %items.keys -> $item-name
{
my $v = 'v' x %items{ $item-name }<v>;
my $w = 'w' x %items{ $item-name }<w>;
$left ~= sprintf( '$<%s> = [ [ %s ]? ] ' ~"\n", $item-name, $v );
$right ~= sprintf( '[ { say "%s"; say $/<%s>; say $0; say $1; $%d } %s || { "" } ]' ~ "\n", $item-name, $item-name, ++$i, $w );
}
use MONKEY-SEE-NO-EVAL;
my $re = sprintf( '%s0' ~ "\n" ~ '<?before ' ~ "\n" ~ '%s>' ~ "\n", $left, $right );
say $re;
dd $/ if $str ~~ m:g/<$re>/;
Odpowiedzi:
Ta odpowiedź obejmuje tylko to, co dzieje się źle. Nie dotyczy rozwiązania. Nie zgłosiłem odpowiednich błędów. Nie przeszukałem nawet kolejek błędów, aby sprawdzić, czy mogę znaleźć raporty odpowiadające jednemu lub obu tym problemom, które ujawniłem.
wyświetla:
Koncentrując się najpierw na pierwszym wywołaniu
debug
(linii zaczynających się1
i kończących narex-var => 「x」
), widzimy, że:Coś poszło nie tak podczas połączenia z
debug
:$<rex-var>
jest zgłaszane jako mające wartośćNil
.Gdy dopasowanie wyrażenia regularnego zostanie zakończone i wrócimy do głównej linii,
say $/
raportuje pełny i poprawnie wypełniony wynik, który zawierarex-var
nazwane dopasowanie.Aby dowiedzieć się, co poszło nie tak, prosimy o przeczytanie dużej części mojej odpowiedzi na inne SO pytanie . Możesz bezpiecznie pominąć Korzystanie
~
. Przypisy 1,2 i 6 są również prawdopodobnie zupełnie nieistotne w twoim scenariuszu.W przypadku drugiego dopasowania widzimy, że nie tylko jest
$<rex-var>
zgłaszany jako będący wNil
trakciedebug
połączenia, ale zmienna końcowego dopasowania, zgłoszona z powrotem w linii głównej wraz z drugimsay $/
, również nierex-var
pasuje. A jedyną różnicą jest to, że regex$regex
jest wywoływana z wewnątrz zewnętrznej regex.źródło