Я использовал дерево сегментов для 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)
Почему переменная экземпляра 'mid'? Похоже, что все вызовы 'build' в дереве вызовов имеют один и тот же' mid'. – user2357112
@ user2357112 Это не должно быть проблемой, поскольку функциональные параметры гарантированно оцениваются перед вызовом функции. правильно? Ну, я новичок в парадигме. поэтому, я не знаю, что является правильным способом иметь локальную переменную. – silentboy
вы вызываете сборку дважды, потому что второй вызов mid будет уже перезаписан первым вызовом – shurik