完成以下带有字符串的方法,对于字符串中的每个重复字符序列,除去其中一个字符。例如,给定输入字符串“AAAABCCDDDDAACCCCCC”,该方法应返回“ABCDAC”。
您的代码必须恢复正常。不要使用任何循环(while,do / while或for)。不要在方法之外声明任何变量。您可以在方法中声明局部变量。
public static String eliminateRepeats (String s)
{
答案 0 :(得分:1)
public class Recurse
{
public static void main( String args[] )
{
System.out.println( recurse( "AAAABCCDDDDAACCCCCC" ) );
}
private static String recurse( String s )
{
if ( s == null || s.equalsIgnoreCase("") )
{
return "";
}
else if ( s.length() > 1 )
{
if ( !s.substring( 0 , 1 ).equalsIgnoreCase( s.substring( 1 , 2 ) ) )
{
return s.substring( 0 , 1 ) + recurse( s.substring( 1 ) );
}
return recurse( s.substring( 1 ) );
}
else
{
return s.substring( 0 , 1 );
}
}
}
答案 1 :(得分:1)
这里的诀窍是你需要一个循环来解决这个问题,所以你只需要通过字符串越来越小的部分递归调用该方法来伪造一个循环。
没有办法将工作分成更小的部分,就像使用递归时一样(例如将字符串分成两半)。您只需要一次处理一个字符,并使用字符串的其余部分调用该方法。
C#中的示例:
public static string EliminateRepeats(string s) {
return
s.Length == 1 ?
s
:
(s[0] != s[1] ? s.Substring(0, 1) : "")
+ EliminateRepeats(s.Substring(1));
}
(代码受Jonathan Paynes代码启发。)
答案 2 :(得分:0)
// use a default value for the lastchar for the first char,
// which is impossible to meet in an regular string
def concentrate (s: String, lastchar: Char = 0) : String = {
// recursive methods always need to know when it is enough
if (s.length == 0) s else
if (s(0) == lastchar) concentrate (s.substring (1), lastchar) else
s(0) + concentrate (s.substring (1), s(0)) }
concentrate ("AAAABCCDDDDAACCCCCC")
这是一个尾递归变体:
@tailrec
def concentrate (s: String, carry:String = "", lastchar: Char = 0) : String = {
if (s.length == 0) carry else
if (s(0) == lastchar) concentrate (s.substring (1), carry, lastchar) else
concentrate (s.substring (1), carry + s(0), s(0)) }
它在最后一个位置有递归调用,因为生成的字符串在运行中粘在一起,并作为参数传递。在Scala中,这可以通过编译器进行优化,以便与具有可变变量的循环一样快地运行,并且它不会破坏堆栈 - 即使对于非常长的字符串也是如此。