Отобразить «путь» хеша от точки входа

Вопросы и обсуждения, касающиеся программирования на Perl.
Ответить
Аватара пользователя
ZEN
Администратор
Сообщения: 1350
Зарегистрирован: 27 сен 2012, 18:23
Темы: 206
Откуда: Украина, Одесса
Статус: Не в сети

Отобразить «путь» хеша от точки входа

Сообщение ZEN » 29 июл 2013, 18:15

[spoiler="Подробное описание задания"]Дан хеш и «точка входа». Отобразить «путь» от точки входа. Если путь зацикливается —
остановится на этапе входа в цикл и сообщить об этом.
Входные данные: файл с точкой входа и хешом. Хеш должен состоять из цифр или букв.
Выходные данные: путь от точки входа. При ошибке ­ на STDOUT слово “error” и описание
ошибки в STDERR.

Пример:
cat test3.txt
one
one=>two, three=>four, four=>five, two=>three, five=>one

./Task2_3.pl test3.txt
one­-two­-three­-four­-five­-one
looped

cat test3.txt
one
one=>two, three=>four, four=>five, two=>three

./Task2_3.pl test3.txt
one­-two­-three­-four­-five[/spoiler]

Код: Выделить всё

#!/usr/bin/perl -w
use strict;

# use first argument of script as file name whith data
my $test_file_path = $ARGV[0];
# open file and get file handler or die
open( FH, "<", "$test_file_path") or die "Can not open test file: $!";
my $first_key = "";
my $str = "";
# line counter
my $count = 0;
while (<FH>) {
    if ($count++ < 2) { # if 1 or 2 line
        my $tmp = $_; # remove \s when needet
        $tmp =~ s/\s*,\s*/,/g;
        $tmp =~ s/^\s*//g;
        $tmp =~ s/\s*$//g;
        if ($count == 1) { # if first step
            $first_key = $tmp; # set key
        } else { # else set string whith hash
            $str = $tmp;
        }
    } else { # if file has more line
        warn("$test_file_path has more then 2 line data");
        last;
    }
}
# if read data empty
if ("" eq $first_key || "" eq $str) {
    print "error\n";
    warn("$test_file_path has less then 2 line data");
    exit -1;
}
# close file handler
close ( FH );

# future hash
my %values;
# split string as array 
my @array = split(/,/, $str);
# fill hash key-values from array 
foreach my $item(@array) {
    my $l_idx = index($item, "=>");
    if ($l_idx == -1) {
        print "error\n";
        warn("String separator not found - [$item]");
        exit -2;
    }

    $l_idx = index($item, "=>", $l_idx+1);
    if ( $l_idx != -1) {
        print "error\n";
        warn("String separator more then one");
        exit -3;
    }
    
    my ($i,$j)= split(/=>/, $item);
    if ($i eq "" || $j eq "") {
        print "error\n";
        warn("Empty key or value - [$i] => [$j]");
        exit -4;
    } else {
        my ($tmp_i, $tmp_j) = ($i, $j);
        $tmp_i =~ s/[a-zA-Z0-9]//g;
        $tmp_j =~ s/[a-zA-Z0-9]//g;
        if ($tmp_i ne "" || $tmp_j ne "") {
            print "error\n";
            warn("Unsupported symbols - [$tmp_i$tmp_j]");    
            exit -5;
        }
    }
    $values{$i} = $j;
}
# processing ...
print $first_key;
my $prev = $values{$first_key};
while (){
    if ( ! exists $values{$prev}) {
        print "-$prev";
        last;
    }
    print "-$prev";
    $prev = $values{$prev};
    if ($prev eq $first_key) {
        print "-$prev\nlooped";
        last;
    }
}
print "\n";
# exit 
exit 0;
бог создал труд и обезьяну
чтоб получился человек
а вот пингвина он не трогал
тот сразу вышел хорошо

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей