【问题标题】:Count the number of recursive calls Java统计递归调用Java的次数
【发布时间】:2016-03-10 21:12:09
【问题描述】:

所以我对 Java 有点陌生,目前正在 uni 上 CS 入门课程。我有个小问题困扰了我好久。我有一个使用“运行长度编码(RLE)”算法“解压缩”输入文本的递归方法。简单地说,如果输入是“qwwwwwwweeeeerrtyyyyyqqqqwEErTTT”,则输出必须是“q9w5e2rt5y4qw2Er3T”。目前,我的方法将输入分解为一个没有数字的字母(qwertyqwErT)。

我的问题是我如何才能真正递归地计算字母数?我不允许在方法之外声明任何变量,这是我的主要问题,因为我在 Stackoverflow 上搜索的所有问题大多使用“全局变量”。但是,我可以声明任意数量的局部变量。

教授还给了我们一个“提示”:

提示 #1:记住字符是由数字代码表示的。您可以按如下方式递减字符变量:

字符 c = '7'; C - ; // c 现在将保存字符 '6'

我尝试通过在我正在使用的输入的末尾添加一个编号字符并在每次出现重复字符时将其递增,然后在有新字符时将其替换到前面来解决此问题,但是也没有工作。

感谢您的帮助!

编辑:

我可能应该包括这样一个事实,即我不允许使用任何类型的循环,并且我可以假设一个角色不会重复超过 (9) 次

【问题讨论】:

    标签: java string recursion char


    【解决方案1】:

    假设您使用递归函数调用的返回值来返回压缩字符串,您可以创建另一个参数来跟踪函数已被调用的次数。通过使用引用变量,它可以充当该方法调用的一种“全局变量”。

    public String compress(..., Integer callCount) 
    {
        callCount++;
    
        ...
    }
    

    然后从您的调用函数中执行类似的操作

    Integer callCount;
    compress(..., callCount);
    System.out.println("Compressed in " + callCount + " iterations");
    

    当然,由于您需要函数本身的值来添加字符重复的次数,因此您也可以在函数中使用callCount

    另一种选择是使用静态变量,这类似于使用全局变量的方法。

    【讨论】:

      【解决方案2】:

      全局变量确实是要避免的。幸运的是,您完全不需要它们来实现 RLE 压缩的纯函数。

      提示允许您直接使用数字(字符)作为计数器。考虑这个片段:

      char c = getNextChar();
      if (Character.isDigit(c)) {
        counter = c;
        char_to_decompress = getNextChar();
        while (c > '0') {
          result.add(char_to_decompress);
          c--; // the 'trick'
        } 
      }
      

      当然,这仅适用于长度不超过 9 个字符的运行。

      WRT 递归,除了替换外循环之外,我没有看到使用它的好方法。 (任何可以用递归表示的东西都可以用循环表示,反之亦然。)

      String decompress(String input) {
        if (input == '') return ''; // this stops recursion
        int position = 0; // where have we advanced
        String result = '';
        if (Character.isDigit(input.charAt(position))) {
          position += 1;
          // ... decompress input.charAt(position) into result
        } 
        else {
          result = input.charAt(position); // not compressed
        }
        // here come recursion
        return result + decompress(input.substring(position + 1)); 
      }
      

      这当然不是经验丰富的 Java 开发人员会做的事情,因为剪切和添加字符串非常慢,您必须使用 StringBuffer 来收集结果并使用 CharSequence 作为输入以允许廉价字符串切片。

      但总体思路仍然存在。这种算法在字符串是列表的语言中看起来会更好,切割列表的头部是一种自然操作,递归是表达循环的基本方式。当/如果你开始了解像 Lisp、Haskell 或 Erlang 这样的语言,你会更清楚地看到这一点。

      【讨论】:

      • 输入字符串不包含数字。
      猜你喜欢
      • 1970-01-01
      • 2021-04-15
      • 1970-01-01
      • 2021-11-20
      • 2012-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多