Perl程序的问题

时间:2016-10-19 00:19:02

标签: perl

use strict;
use warnings;
use FindBin;
use lib $FindBin::Bin;
use genNumeros;

my @palabra;

open (my $ARCHIVO, '<', "palabras.txt") or warn ("No se encontro el archivo     palabras.txt, $!");
while (my $palabra = <$ARCHIVO>) {
    chomp $palabra;             

    push @palabra, $palabra;   
}
close $ARCHIVO;
my $palabraAleatoria = $palabra[genNumeros::crearNumero()];
print"$palabraAleatoria";
<>;

genNumeros模块有以下代码:

 package genNumeros;
 use strict;
 use warnings;
 use Math::Complex;


my $seed = time();
my $a = $seed / 5;
my $c = $seed - 7;
my $x = $seed;
my $m = sqrt($seed % 574) + $seed;
my $numAleatorio;


sub generadorMultiplicativo{
    $numAleatorio = ((($a*$x) + $c) % $m);
    $x = $numAleatorio;
}
my $letra;
my $residuo;

sub crearNumero{

generadorMultiplicativo();
     $residuo = $x/$m;

   if($residuo < 0.0384615384615385){
       $letra = 1;
   } 
   if($residuo > 0.0384615384615385 && $residuo < 0.076923076923077){
           $letra = 2;
   } 
   if($residuo > 0.076923076923077 && $residuo < 0.1153846153846154){
           $letra = 3;
   }
   if($residuo > 0.1153846153846154 && $residuo < 0.1538461538461538){
           $letra = 4;
   }
   if($residuo > 0.1538461538461538 && $residuo < 0.1923076923076923){
           $letra = 5;
   }
   if($residuo > 0.1923076923076923 && $residuo < 0.2307692307692308){
           $letra = 6;
   }
   if($residuo > 0.2307692307692308 && $residuo < 0.2692307692307692){
           $letra = 7;
   }
   if($residuo > 0.2692307692307692 && $residuo < 0.3076923076923077 ){
           $letra = 8;
   }
   if($residuo > 0.3076923076923077 && $residuo < 0.3461538461538462){
           $letra = 9;
    }
   if($residuo > 0.3461538461538462 && $residuo < 0.3846153846153846){
           $letra = 10;
   }
   if($residuo > 0.3846153846153846 && $residuo < 0.4230769230769231){
           $letra = 11;
   }
   if($residuo > 0.4230769230769231 && $residuo < 0.4615384615384615){
           $letra = 12;
    }
    if($residuo > 0.4615384615384615 && $residuo < 0.5){
           $letra = 13;
   }
   if($residuo > 0.4615384615384615 && $residuo < 0.5384615384615385){
           $letra = 14;
   }
   if($residuo > 0.5384615384615385 && $residuo < 0.5769230769230769){
           $letra = 15;
   }
   if($residuo > 0.5769230769230769 && $residuo < 0.6153846153846154){
           $letra = 16;
   }
   if($residuo > 0.6153846153846154 && $residuo < 0.6538461538461538){
           $letra = 17;
   }
   if($residuo > 0.6538461538461538 && $residuo < 0.6923076923076923){
           $letra = 18;
   }
   if($residuo > 0.6923076923076923 && $residuo < 0.7307692307692308){
           $letra = 19;
   }
   if($residuo > 0.7307692307692308 && $residuo < 0.7692307692307692){
           $letra = 20;
   }
   if($residuo > 0.7692307692307692 && $residuo < 0.8076923076923077){
           $letra = 21;
   }
   if($residuo > 0.8076923076923077 && $residuo < 0.8461538461538462){
           $letra = 22;
   }
   if($residuo > 0.8461538461538462 && $residuo < 0.8846153846153846){
           $letra = 23;
   }
   if($residuo > 0.8846153846153846 && $residuo < 0.9230769230769231){
           $letra = 24;
   }
   if($residuo > 0.9230769230769231 && $residuo < 0.9615384615384615){
           $letra = 25;
   }
   if($residuo > 0.9615384615384615 && $residuo < 1){
           $letra = 26;
   }
   return $letra;

}

1;

问题是,当我执行.pl时,它只会关闭,我已经检查了&#34; palabras.txt&#34;它有27个单词,perl -c和perl -wc表示语法没问题,带有perl -V的@INC用&#39;结束。我真的不知道&和#39; s发生了,我在Windows 10中使用ActivePerl 5.20。

1 个答案:

答案 0 :(得分:3)

您的代码正在运行,但它不会在窗口关闭之前显示数字。

STDOUT(打印到屏幕上)通常为line buffered。这意味着它只会在看到换行符时显示该行。例如......

print "SLEEP!!!";
sleep 2;
print " AWAKE!!!\n"'

这将睡眠两秒钟,然后一次打印SLEEP!!! AWAKE!!!

尝试print "$palabraAleatoria\n";

有关详细信息,请阅读Suffering From Buffering

好像你正在制作自己的随机数发生器? Perl已经有一个rand(),它将使用比秒数更好的种子,以及更好的算法。 rand需要生成一系列数字。 rand(27)将给出0到27之间的数字(0到26.9999)。要使用它从数组中挑选元素,请使用数组的大小。

my $random_idx = int rand @palabra;
print "$palabra[$random_idx]\n";

这也避免了必须将数组中元素的数量硬编码到代码中。

使用rand消除了对大if链的需求,但无论如何我们都要讨论它。从顶部开始可以更好地写成if/elsif

if( $residuo > 0.9615384615384615 ) {
    return 26;
}
elsif( $residuo > 0.9230769230769231 ) {
    return 25;
}
...and so on...

这避免了必须复制范围两次意味着错别字的机会。 if/elsif效率更高,不必检查每个条件,只要满足条件就会停止。立即返回比使用中间返回变量更简单,更有效。

所有这些神奇的数字让人怀疑为什么它们是神奇的。一旦你注意到0.0384615384615385是1/26,你就可以使用它。

if( $residuo > 25/26 ) {
    return 26;
}
elsif( $residuo > 24/26 ) {
    return 25;
}
...and so on...

用分数替换幻数可以更容易阅读和清除正在发生的事情。一旦发生这种情况,很明显可以用一些简单的数学代替。

return $residuo * 26 + 1;