Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java递归;我如何简化我所拥有的?_Java_Recursion - Fatal编程技术网

Java递归;我如何简化我所拥有的?

Java递归;我如何简化我所拥有的?,java,recursion,Java,Recursion,我必须编写以下递归方法: public static int countA(String s) 然而,我发现如果不声明计数器和位置变量,就不可能做到这一点;像这样: public static int countA(String s, int position) { int count = 0; if( s.charAt(position) == 'A' ) count++; if( position + 1 <

我必须编写以下递归方法:

public static int countA(String s)
然而,我发现如果不声明计数器和位置变量,就不可能做到这一点;像这样:

public static int countA(String s, int position) {

        int count = 0;

        if( s.charAt(position) == 'A' )
            count++;

        if( position + 1 < s.length() ) {
            count += countA(s, position + 1);
        }

        return count;
    }
public static int countA(字符串s,int位置){
整数计数=0;
如果(s.charAt(位置)=‘A’)
计数++;
如果(位置+1
如何简化我的答案,使我的方法与列出的方法相同

编辑:是的,我想计算字符串中的所有A。

试试这个:

public static int countA(String s) {
    int count = 0;

    if (s == null)
        return 0;

    if (s.length() == 0)
        return 0;

    if (s.charAt(0) == 'A')
        count++;

    return count + countA(s.substring(1));
}
试试这个:

public static int countA(String s) {
    int count = 0;

    if (s == null)
        return 0;

    if (s.length() == 0)
        return 0;

    if (s.charAt(0) == 'A')
        count++;

    return count + countA(s.substring(1));
}
那么:

public static int countA(String s) {
        if(s==null) return 0;
        if(s.length()==0) return 0;
        if( s.charAt(0) == 'A' )
        {
            return 1 + countA(s.substring(1));
        } else 
        {
            return countA(s.substring(1));
        }
    }
那么:

public static int countA(String s) {
        if(s==null) return 0;
        if(s.length()==0) return 0;
        if( s.charAt(0) == 'A' )
        {
            return 1 + countA(s.substring(1));
        } else 
        {
            return countA(s.substring(1));
        }
    }

我认为像这样的事情应该会奏效 这里我们假设countA返回字符串s中As的数目

public static int countA(String s)
{
    if(s.length()==0) return 0;  // return 0 if string is empty
    else
    {
        // if the first char is A add 1 to the answer, recurse
        if(s.toCharArray()[0])=='A') return 1+countA(s.subString(1,s.length()));

        // else add nothing to the answer, recurse
        else return countA(s.subString(1,s.length()));
    }
} 

我认为像这样的事情应该会奏效 这里我们假设countA返回字符串s中As的数目

public static int countA(String s)
{
    if(s.length()==0) return 0;  // return 0 if string is empty
    else
    {
        // if the first char is A add 1 to the answer, recurse
        if(s.toCharArray()[0])=='A') return 1+countA(s.subString(1,s.length()));

        // else add nothing to the answer, recurse
        else return countA(s.subString(1,s.length()));
    }
} 

位置
变量移出该方法,使其成为
静态
(因为
countA()
也是
静态

static int position=0;
公共静态int countA(字符串s){
整数计数=0;
如果(s.charAt(位置)=‘A’)
计数++;
如果(位置+1
位置
变量移出方法,使其成为
静态
(因为
countA()
也是
静态

static int position=0;
公共静态int countA(字符串s){
整数计数=0;
如果(s.charAt(位置)=‘A’)
计数++;
如果(位置+1
理想情况下,首先是终止条件,然后通常通过减少缩进/嵌套来简化代码,并对其执行“不做任何事情”的操作(通常需要比绝对需要多进行一次迭代)

您也不需要局部变量

public static int countA(String s, int position) {
    if (position == s.length())
        return 0;
    return (s.charAt(position) == 'A' ? 1 : 0) + countA(s, position + 1);
}

理想情况下,首先是终止条件,然后通常通过减少缩进/嵌套来简化代码,并对其执行“不做任何事情”操作(通常需要比绝对需要多进行一次迭代)

您也不需要局部变量

public static int countA(String s, int position) {
    if (position == s.length())
        return 0;
    return (s.charAt(position) == 'A' ? 1 : 0) + countA(s, position + 1);
}

递归有两种形式

  • 尾部递归:返回值是当前子例程的值和下一次调用的返回值的组合。例如

    int factorial(int a) {
        if(a==0)
            return 1;
        else
            return a * factorial( a-1 );
    }
    
  • 基于累加器的递归:通过添加额外的参数来累加结果,并返回累加值

    int factorial(int a, int fact) {
        if(a==0)
            return fact;
        else
            return factorial(a-1, a*fact);
    }
    
显然,这里的内容是基于累加器的,而您可以将其改进为尾部递归

尾部递归被认为更具可读性,但它可能导致堆栈溢出!(没有双关语)。这是因为它必须在再次调用子例程之前将当前值推送到堆栈中。当您进行大量此类调用时,此堆栈可能会超出其限制


为了避免这个问题,一些编译器优化了基于累加器的尾部递归。

有两种递归形式

  • 尾部递归:返回值是当前子例程的值和下一次调用的返回值的组合。例如

    int factorial(int a) {
        if(a==0)
            return 1;
        else
            return a * factorial( a-1 );
    }
    
  • 基于累加器的递归:通过添加额外的参数来累加结果,并返回累加值

    int factorial(int a, int fact) {
        if(a==0)
            return fact;
        else
            return factorial(a-1, a*fact);
    }
    
显然,这里的内容是基于累加器的,而您可以将其改进为尾部递归

尾部递归被认为更具可读性,但它可能导致堆栈溢出!(没有双关语)。这是因为它必须在再次调用子例程之前将当前值推送到堆栈中。当您进行大量此类调用时,此堆栈可能会超出其限制


为了避免这个问题,一些编译器优化了基于累加器的尾部递归。

请至少解释一下该方法实际应该做什么。我认为OP想要计算字符串中的“A”要计算字符串中的所有A,我不会使用递归,使用一个穿过字符串的循环来简化它。@boskop:这显然不是本练习的重点。为了学习递归,可能需要使用递归。设计这样的方法来获得那个数字是很奇怪的。在这方面,递归的代价比预期的要高。请至少解释一下该方法实际应该做什么。我认为OP想要计算字符串中的“A”要计算字符串中的所有A,我不会使用递归,请使用遍历字符串的循环来简化它。@boskop:这显然不是本练习的重点。为了学习递归,可能需要使用递归。设计这样的方法来获得那个数字是很奇怪的。在这方面,递归的代价比预期的要高。