2015-11-07 6 views
0

Я использовал дерево сегментов для RSQ. Я заметил что-то, что не имеет смысла. Вот воспроизведен версия оригинального кода:Почему этот рекурсивный вызов работает таким образом?

#include <iostream> 
#include <vector> 
using namespace std; 

class ST { 
    private: 
    int siz, mid; 
    void build(int n, int l, int r) 
    { 
     cout << n << " " << l << " " << r << endl; 
     if(l == r){ 
      //some op 
     } else { 
      mid = (l+r)/2; 
      build(2*n, l, mid); 
      build(2*n+1, mid+1, r); 
      //some op 
     } 
    } 
    public: 
    ST(vector<int> &x) 
    { 
     siz = x.size(); 
     build(1, 0, siz-1); 
    } 
}; 

int main() 
{ 
    vector<int> p; 
    int t, z; 

    cin >> t; 
    while(t--) 
    { 
     cin >> z; 
     p.push_back(z); 
    } 
    ST c(p); 

    return 0; 
} 

Теперь, если вектор р имеет размер 3, первый раз сборки называется с (1, 0, 2), как и ожидалось. Но он должен быть рекурсивно переходить на build(2, 0, 1) и build(3, 2, 2). первая работает правильно, где вторая называется build(3, 1, 2). Похоже, что mid+1 производит mid. Что я упустил?

g++ -v показывает GCC версии 4.8.4 (Ubuntu 4.8.4-2ubuntu1 ~ 14,04)

+3

Почему переменная экземпляра 'mid'? Похоже, что все вызовы 'build' в дереве вызовов имеют один и тот же' mid'. – user2357112

+0

@ user2357112 Это не должно быть проблемой, поскольку функциональные параметры гарантированно оцениваются перед вызовом функции. правильно? Ну, я новичок в парадигме. поэтому, я не знаю, что является правильным способом иметь локальную переменную. – silentboy

+1

вы вызываете сборку дважды, потому что второй вызов mid будет уже перезаписан первым вызовом – shurik

ответ

1

По комментариям - билд вызываются дважды подряд и для второго вызова среднего переменного экземпляра уже переписан первый звонок.

Я не публиковал это изначально как ответ, потому что даже когда я сделал среднюю локальную переменную, я все равно не смог получить ожидаемые вами числа. Но рад, что это помогло :)

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