-1

该子例程使用从 A 到长度为 N 的字母的第 M 个字母生成字母的字符串组合。

sub genString
{
   my($m,$n,$str,$letter,$temp,$i) = @_;
   if($n == 0){
      $letter = chr(ord("A")+($i+=1));
       if($temp == 1){ print "$str\n"; }
       else{
          for($j = 0 ; $j < temp-1 ; $j++){
             if(ord(substr($str,$j,1)) < ord(substr($str,$j+1,1))){$do_print = 1;}
             else{
                $do_print = 0;
                break;
             }
          }
       if($do_print == 1){ print "$str\n"; }
       }
   }
   else{
       for($j = ord($letter) ; $j < ord($letter)+$m ; $j++){
           genString($m,$n-1,$str.chr($j),$letter,$temp,$i);
      }
   }
}
&genString($m,$n,$str,"A",$n,0);

示例:输入:M=4;N=3;输出:ABC ABD ACD BCD

我在 Ruby 中尝试过类似的方法,它可以工作,但在 Perl 中,这是一个无限循环,我不知道为什么。我是 Perl 的新手。我应该怎么办?(对不起,如果我的代码有点长)

4

3 回答 3

3

默认情况下,变量是 perl 中的全局变量(尽管 将阻止未声明和不合格的使用它们use strict)。为了使您的递归起作用,您需要使其中一些成为词法,例如,更改:

for($j = 0 ; $j < temp-1 ; $j++){

for (my $j = 0; $j < $temp-1; $j++) {

或者更好,只是

for my $j (0..$temp-2) {
于 2012-08-24T19:06:18.453 回答
3

请始终在您的代码中使用use strict;use warnings;,尤其是在发布代码和寻求帮助时。也总是用 . 声明局部变量my

在这种情况下,即使没有尝试过,我也很确定像$j引用全局变量这样的事情会让你很头疼——有些事情use strict会被抓住。

于 2012-08-24T18:46:18.650 回答
1

您的代码很难阅读。我看不懂算法,也看不到子程序这么多参数的目的,尤其是$temp看起来没有改变,而且你没有说它的初始值在最外面的调用中设置为什么.

此代码似乎可以使用类似的算法执行您想要的操作

use strict;
use warnings;

genString(4, 3);

sub genString {

   my ($m, $n, $str, $i) = @_;

   if ($n == 0) {
     print $str, "\n";
   }
   else {
     for my $off ($i // 0 .. $m - $n) {
       $str //= '';
       genString($m, $n-1, $str.chr(ord('A') + $off), $off+1);
     }
   }
}

输出

ABC
ABD
ACD
BCD
于 2012-08-24T19:13:54.207 回答