计算递归调用Java的数量

时间:2015-12-06 03:33:19

标签: java string recursion char

所以我对Java有点新意,目前正在大学学习CS入门课程。我有一个小问题,一直困扰着我。我有一个写一个递归方法,"解压缩"输入文本使用a"游程编码(RLE)"算法。简而言之,如果输入是" qwwwwwwwwweeeeerrtyyyyyqqqqwEErTTT"输出必须是" q9w5e2rt5y4qw2Er3T"。目前,我的方法将输入分解为只有一个字母而没有数字(qwertyqwErT)。

我的问题是如何实际计算递归的字母数?我不允许在方法之外声明任何变量并且这是我的主要问题,因为我在Stackoverflow上搜索的所有问题大多使用"全局变量"。但是,我可以根据需要声明尽可能多的局部变量。

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

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

char c =' 7&#39 ;; C - ; // c现在将保留角色' 6'

我试着通过在输入的末尾添加一个带编号的字符来解决这个问题,我每次都会使用并递增一个重复的字符然后将其替换为前面的#&# 39;一个新角色,但那也没有。

感谢您的帮助!

编辑:

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

2 个答案:

答案 0 :(得分:1)

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

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

    ...
}

然后从您的调用函数

执行类似的操作
Integer callCount;
compress(..., callCount);
System.out.println("Compressed in " + callCount + " iterations");

当然,由于你需要函数本身的值来添加一个字符重复的次数,所以没有什么能阻止你在函数中使用callCount

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

答案 1 :(得分:0)

全局变量确实是要避免的事情。幸运的是,你完全不需要它们来实现一个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这样的语言时,你会更清楚地看到这一点。