Использование Array в Perl для ввода данных пользователем и вычисления результатов - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть довольно сложное вычисление, которое нужно сделать на основе пользовательского ввода и файла value.txt, который нужно вычислить с помощью сценария perl. Пользователь может выбрать ввод из алфавитов GCA U. Ввод может быть любой длины, но комбинация из 4 упомянутых алфавитов. Основываясь на вводе, мне нужно будет соединить каждый алфавит с соседним до последнего и распечатать их. Тогда каждая пара имеет заранее определенное значение, которое необходимо добавить и вывести окончательный результат. Например:

> input by user after script prompt : ACCGUA
> 
> Script need to pair : AC CC CG GU UA
> 
> read the value of each pair from a values file below:
> 
> value.txt
> 
> AC = 2 CC = 1 CG = AC  GU = UG UG = 4 UA = 0
> 
> Output should be  
> 
>  total value is  9 (2+1+2+4+0)

Я пробовал что-то в оболочке, определив массив, но ничего не нашел в perl.

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Кажется, это делает то, что вы хотите. Возможно, вы захотите добавить еще немного проверки ошибок.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';
use List::Util 'sum';

my %value_map = load_value_map();

my $input = shift // '';
$input =~ s/[^ACGU]//g;

until ($input) {
  print 'Give me a string of letters [ACGU]: ';
  chomp ($input = <STDIN>);
  $input =~ s/[^ACGU]//g;
}

my @values;

for (0 .. length($input) - 2) {
  my $str = substr $input, $_, 2;
  if (exists $value_map{$str}) {
    push @values, $value_map{$str};
  } else {
    warn "$str is not a valid map key\n";
    next;
  }
}

say 'total value is ', sum(@values), ' (', join('+', @values), ')';

sub load_value_map {
  open my $fh, '<', 'value.txt' or die $!;

  my %value_map = map { chomp; split } <$fh>;

  for (keys %value_map) {
    if ($value_map{$_} =~ /\D+/) {
      $value_map{$_} = $value_map{$value_map{$_}};
    }
  }

  return %value_map;
}
0 голосов
/ 06 ноября 2019

Вот пример (с использованием объектно-ориентированного Perl):

#! /usr/bin/env perl

Compute->new( fn => 'value.txt' );

package Compute;
use feature qw(say);
use strict;
use warnings;

sub new {
    my ( $class, %args ) = @_;
    my $self = bless \%args, $class;

    $self->read_map();
    $self->cleanup_map();
    $self->input_text();
    $self->gen_pairs();
    $self->compute_sum();
}

sub compute_sum {
    my ( $self ) = @_;

    my $map = $self->{map};
    my $sum = 0;
    for my $pair ( @{ $self->{pairs} } ) {
        if ( exists $map->{$pair} ) {
            $sum += $map->{$pair};
        }
        else {
            die "Undefined pair: '$pair'\n";
        }
    }
    say "Sum = ", $sum;
}

sub gen_pairs {
    my ( $self ) = @_;

    my $txt = $self->{txt};
    my @chars = split //, $txt;
    my @pairs;
    for my $i (0..($#chars - 1)) {
        push @pairs, $chars[$i] . $chars[$i+1];
    }
    $self->{pairs} = \@pairs;
}

sub input_text {
    my ( $self ) = @_;

    print "Enter text: ";
    my $txt = <STDIN>;
    if ( defined $txt ) {
        $txt =~ s/^\s+//;
        $txt =~ s/\s+$//;
        if ( (length $txt) >= 2 ) {
            $self->{txt} = $txt;
            return;
        }
    }
    say "No input.";
    exit;
}

sub cleanup_map {
    my ( $self ) = @_;

    my $map = $self->{map};
    while (1) {
        my $modified = 0;
        for my $key ( keys %$map ) {
            my $value = $map->{$key};
            if ( $value =~ /^[A-Za-z]+$/ ) {
                if ( exists $map->{$value} ) {
                    $map->{$key} = $map->{$value};
                    $modified = 1;
                }
                else {
                     die "Undefined value: '$value'\n";
                }
            }
        }
        last if !$modified; 
    }
}

sub read_map {
    my ( $self ) = @_;

    my $fn = $self->{fn};
    my %map;
    open ( my $fh, '<', $fn ) or die "Could not open file '$fn': $!";
    while( my $line = <$fh> ) {
        chomp $line;
        my ( $key, $value ) = split " ", $line;
        if ( (defined $key) && (defined $value) ) {
            if ( length $key != 2 ) {
                die "Bad input key\n";
            }
            $map{$key} = $value;
        }
    }
    close $fh;
    $self->{map} = \%map;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...