Хвостовая рекурсия — Java

Я пытаюсь создать метод, который является хвостовым рекурсивным и находит sum уравнения (i / 2i + 1), где i нужно увеличить 1-10. У меня возникли проблемы с тем, как достичь базового случая и остановить рекурсию.

Это то, что у меня есть до сих пор:

public class SumSeries {

    public static void main(String[] args) {
        System.out.println(sumSeries());
    }

    public static double sumSeries(){
        int i = 10;

        if (i == 0)
            return 0;
        else
            return (i / (2 * i + 1));
    }
}

person Monocyte    schedule 09.04.2015    source источник
comment
Итак, ваш метод не содержит рекурсию. Рекурсия означает: вызов метода A из метода A. Но вы не вызываете sumSeries() в теле вашего метода?! Может быть, ваш оператор else должен читаться как return sumSeries(i ...   -  person GhostCat    schedule 09.04.2015
comment
stackoverflow.com/questions/3616483/   -  person Paweł Adamski    schedule 09.04.2015
comment
Я не уверен, что вы спрашиваете. Уравнение похоже на (1 / 2 * 1 + 1) + (2 / 2 * 2 + 1) + (3 / 2 * 3 + 1) + ...? Кроме того, как указывали другие, рекурсия означает, что функция вызывает себя. Ваш код этого не делает.   -  person futureelite7    schedule 09.04.2015
comment
@futureelite7 Да, именно так должно работать уравнение.   -  person Monocyte    schedule 09.04.2015


Ответы (4)


Если вам нужна рекурсия, ваш метод должен выглядеть примерно так:

public class SumSeries {

    public static void main(String[] args) {
        System.out.println(sumSeries());
    }

    // if you want to keep the argument-less method in main but want to calculate
    // the sum from 1 - 10 nevertheless.
    public static double sumSeries() {
      return sumSeries(10);
    }

    public static double sumSeries(int i){
        if (i == 0) {
            return 0;
        }
        else {
            // The cast to double is necessary. 
            // Else you will do an int-division here and get 0.0 as result.
            // Note the invocation of sumSeries here inside sumSeries.
            return ((double)i / (2 * i + 1)) + sumSeries(i-1);
        }
    }
}
person QBrute    schedule 09.04.2015
comment
Этот ответ близок, но когда я запустил задачу в онлайн-калькуляторе, сумма была 6,066... ​​но с этим кодом сумма равна 4,40, потому что sumSeries(i-1) вычитается из суммы. Как мне сохранить этот код, чтобы я мог достичь базового случая, но удалить его из уравнения? - person Monocyte; 09.04.2015
comment
Сумма 6,066 неверна. См. здесь:. И я ничего не вычитал в этом методе. Я просто суммирую все элементы от 10 до 1. Это просто обратный порядок :) - person QBrute; 09.04.2015
comment
о, спасибо. я использовал именно этот сайт и получил сумму 6,066. ошибка пользователя. :) - person Monocyte; 09.04.2015

Я думаю, что вы ищете что-то вроде этого:

public class SumSeries {

    public static void main(String[] args) {
        System.out.println(sumSeries(10,0));
    }

    public static double sumSeries(int i,double result){

        if (i == 1)
            return result;
        else{
          double res = result + (i / (double)(2 * i + 1));
          return sumSeries(i-1,res);
       }
   }
}
person Thanos Pappas    schedule 09.04.2015
comment
проверьте сейчас, я забыл двойное приведение, извините за это :) - person Thanos Pappas; 09.04.2015
comment
Базовый случай должен быть 1, а не 0, ОП сказал, что i увеличивается с 1 до 10 - person blackbishop; 09.04.2015

Если вы ищете способ найти эту сумму:

(1 / 2*1 + 1) + (2 / 2*2 + 1) + (3 / 2*3 + 1) + ... + i/(2i + 1)

Вы можете попробовать это:

public double sumSeries(int i) {
   if (i == 1) { // base case is 1 not 0
     return 1/3;
   } else {
     double s = i / (2.0 * i + 1.0);
     return s + sumSeries(i - 1);
   }
} 
person blackbishop    schedule 09.04.2015

Ваш метод не является рекурсивным. Рекурсивный метод должен использовать «самого себя», и при определенном условии он останавливается. Пример:

public static double sumSeries(int x) { 
    if (x == 0)   
        return x;
    else {  
        return x + sumSeries(x - 1);
}

для вашего примера подойдет что-то вроде этого:

public static double sumSeries(double x) {
    if (x == 0)   
        return x;
    else  
        return (x / (2 * x + 1)) + sumSeries(x - 1.0); 
}

Если я правильно понял ваш алгоритм :) Если нет, отредактируйте алгоритм :)

person Dopdop    schedule 09.04.2015