2014-04-24 5 views
0

Я написал программу Perl, которая принимает в качестве входных 2 текстовых файла.Изменить входной файл в Perl

Первый файл содержит последовательности и вероятности с этим форматом

good morning 0.5 

Второй файл содержит все слова с их вероятностями с этим форматом

good 0.5 
morning 0.6 

Мой скрипт вычисляет формулу для каждой последовательности

log(prob(sequence)/(prob(word1) - prob(sequence)) * (prob(word2) - prob(sequence))) 

Проблема в том, что у меня так мне случаи, когда prob(sequence) таких же, как prob(word1) или prob(word2) так что я получаю Illegal division by zero

Есть ли способ изменить значение во втором файле путем добавления десятичного в этих случаях? (Сглаживание)

#!/usr/bin/perl 
use strict; ## PLE 
use warnings; 

my $inFile = "file1.txt"; 
my $outFile ="TEST.txt"; 
my %hashFR = getVocab("file2.txt"); 
my @result; 

my $bloc = 50000; 
my $cmp = 0; 

open fileIn, "<$inFile" or die $!; 
while (<fileIn>) { 
    chomp; 
    my $flag = 0; 
    my $ligne = $_; 
    my @words = getWords($ligne); 
    if (my $prob = pop @words) { 
     $prob =~ s/\(//g; 
     my $probWords = 1; 

     foreach my $word (@words) { 
      my $probWord; 
      if (exists $hashFR{$word}) { 
       $probWord = $hashFR{$word}; 
      } 
      $probWords *= $probWord-$prob; 
     } 

     my $calc = $prob*log2($prob/($probWords)); 
     my $result10 = sprintf("%.10f", $calc); 
     push @result, join(' ',@words) ." (".$result10.")\n"; 
    } 
} 

#if(scalar(@result) == $bloc) 
{ 
    $cmp += $bloc; 
    print "$cmp lignes traités\n"; 
    writeToResultFile($outFile,@result); 
    @result =(); 
} 

sub getWords { 
    my ($ligne) = $_; 

    my @words = split(' ', $ligne); 

    return @words; 
} 

sub getVocab { 
    my ($filename) = @_; 
    my %hash =(); 

    open fileVocab, "<$filename" or die $!; 
    while (<fileVocab>) { 
     chomp; 

     if (2 == (my($mot, $prob) = split(/ /))) { 
      $hash{trim($mot)} = trim($prob); 
     } 
    } 
    close fileVocab; 
    return %hash; 
} 

sub writeToResultFile { 
    my ($filename,@res) = @_; 
    open(INFO, ">>$filename"); 
    foreach (@res) { 
     print INFO $_; 
    } 
    close INFO 
} 
sub log2 { 
    my $n = shift; 
    return (log($n)/log(10))/(log(2)/log(10)); 
} 

sub trim($) { 
    my $string = shift; 
    $string =~ s/^\s+//; 
    $string =~ s/\s+$//; 
    return $string; 
} 
+0

Пожалуйста, вы могли бы дать пример своего рода chnage вы хотите сделать ? – Borodin

ответ

2

Вы можете использовать обработку исключений, как это:

my $calc 
eval { 
$calc = $prob*log2($prob/($probWords)); 
}; 
if ([email protected]){ 
    $calc = 0;#or whatever suits you 
} 

Или еще проще:

my $calc = eval { $prob*log2($prob/($probWords)) } // 'NaN'; 
Смежные вопросы