2016-09-01 2 views
2

Я написал программу java для добавления элементов в массив с использованием Linear Recursion. Полученный результат не соответствует ожиданиям. Может ли кто-нибудь указать, что не так с этой программой?Как работает линейная рекурсия?

public class TestSum { 

    public int count = 0; 


    public int sum(int[] a){ 

     count++; 

     if(a.length == count){ 
      return a[count -1]; 
     } 

     return sum(a) + a[count -1] ; 
    } 

    public static void main(String[] args) { 

     int[] a = {1,2,3}; 

     int val = new TestSum().sum(a); 
     System.out.println(val); 
    } 

} 

Я ожидаю выход как 6, но полученный . Что не так?

Странно, если я изменяю порядок добавления, то есть return a[count -1] + sum(a);, тогда он дает выходные данные как .

+1

«Как ни странно, если я изменю порядок добавления, верните [count -1] + sum (a), а затем выдаст результат как 6." Почему ты находишь это странным? – bradimus

+0

Мне кажется странным, что выход изменяется только путем изменения порядка сложения. Я имею в виду, что 2 +3 совпадает с 3 + 2. Я уверен, что мое понимание о рекурсии неверно и пытается понять то же самое. – user001

+0

Но вы не добавляете константы здесь. 'sum (a)' изменяет значение 'count' и, таким образом, изменяет' a [count-1] '. – bradimus

ответ

6

В целом, рекурсивные программы, которые не являются повторителями (т. Е. Полагаются на внешнее состояние), являются подозрительными. В вашем конкретном случае count будет меняться между вызовами sum, что затрудняет отслеживание поведения и, в конечном итоге, приводит к ошибке, которую вы наблюдаете.

Вы должны пройти индекс наряду с массивом, чтобы заставить его работать:

// The actual implementation passes the starting index 
private static int sum(int[] a, int start){ 
    if(a.length == start){ 
     return 0; 
    } 
    return sum(a, start+1) + a[start]; 
} 
// Make sure the method can be called with an array argument alone 
public static int sum(int[] a) { 
    return sum(a, 0); 
} 

В отличие от реализации, которая увеличивает счетчик внешних по отношению к способу, эта реализация может быть вызвана одновременно на несколько потоков, не нарушая.

+0

Согласитесь с вашим ответом, но до сих пор не понял, почему это ошибка, когда счет объявлен вне? – user001

+0

@ user001 Поскольку вы не можете свободно ссылаться на 'count', не думая, как это будет изменено рекурсивным вызовом вашего собственного метода. Значение 'count-1' в строках' return a [count -1]; 'и' return sum (a) + a [count -1] 'отличается, потому что есть вызов' sum (a) 'in между ними. Это то, что вам нужно, чтобы следить за тем, когда вы сохраняете состояние вызова внешним по отношению к вашему методу. – dasblinkenlight

Смежные вопросы