【问题标题】:What's the mistake in my recursive subroutine?我的递归子程序有什么错误?
【发布时间】:2012-08-24 18:39:38
【问题描述】:

该子例程使用从 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 的新手。我该怎么办? (对不起,如果我的代码有点长)

【问题讨论】:

  • 剪切粘贴实际代码会有所帮助
  • temp-1 是错字吗?我应该是$temp-1
  • Perl 中没有break,你很可能想在那里使用last
  • 请确保您的代码在此处发布之前可以编译。请参阅 perldoc perlrun 并阅读有关 -c 开关的信息。

标签: string perl loops recursion subroutine


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

    或者更好,只是

    for my $j (0..$temp-2) {
    

    【讨论】:

      【解决方案3】:

      您的代码很难阅读。算法看不懂,看不到子程序这么多参数的目的,特别是$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-11-05
        • 2012-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-21
        • 2021-06-28
        • 2020-03-08
        相关资源
        最近更新 更多