2013-03-12 73 views
1

我正在練習ACM問題以成爲更好的程序員,但我對C++仍然相當陌生,而且我在解讀某些正在閱讀的評委代碼時遇到了麻煩。一類的開頭C++奇怪的類聲明

public: 
    State(int n) : _n(n), _p(2*n+1) 
    { 

開始,再後來它與

State s(n); 
s(0,0) = 1; 

我想讀的代碼,但我不能使這個意義上說初始化。 State類似乎只有1個參數通過,但程序員在初始化時傳遞了2個參數。另外,究竟是什麼設置= 1?據我所知,=運算符沒有被超載,但萬一我錯過了一些我已經包括在下面的完整代碼。

任何幫助將不勝感激。

在此先感謝

/* 
    * D - Maximum Random Walk solution 
    * ICPC 2012 Greater NY Regional 
    * Solution by Adam Florence 
    * Problem by Adam Florence 
    */ 

    #include <cstdio> // for printf 
    #include <cstdlib> // for exit 
    #include <algorithm> // for max 
    #include <iostream> 
    #include <vector> 

    using namespace std; 

    class State 
    { 
    public: 
     State(int n) : _n(n), _p(2*n+1) 
      { 
      if (n < 1) 
      { 
      cout << "Ctor error, n = " << n << endl; 
      exit(1); 
      } 
      for (int i = -n; i <= n; ++i) 
      _p.at(i+_n) = vector<double>(n+1, 0.0); 
      } 

     void zero(const int n) 
      { 
      for (int i = -n; i < n; ++i) 
      for (int m = 0; m <= n; ++m) 
       _p[i+_n][m] = 0; 
      } 

     double operator()(int i, int m) const 
      { 
    #ifdef DEBUG 
      if ((i < -_n) || (i > _n)) 
      { 
      cout << "Out of range error, i = " << i << ", n = " << _n << endl; 
      exit(1); 
      } 
      if ((m < 0) || (m > _n)) 
      { 
      cout << "Out of range error, m = " << m << ", n = " << _n << endl; 
      exit(1); 
      } 
    #endif 
      return _p[i+_n][m]; 
      } 

     double& operator()(int i, int m) 
      { 
    #ifdef DEBUG 
      if ((i < -_n) || (i > _n)) 
      { 
      cout << "Out of range error, i = " << i << ", n = " << _n << endl; 
      exit(1); 
      } 
      if ((m < 0) || (m > _n)) 
      { 
      cout << "Out of range error, m = " << m << ", n = " << _n << endl; 
      exit(1); 
      } 
    #endif 
      return _p[i+_n][m]; 
      } 

     static int min(int x, int y) 
     { 
      return(x < y ? x : y); 
     } 
     static int max(int x, int y) 
     { 
      return(x > y ? x : y); 
     } 

    private: 
     int _n; 

     // First index is the current position, from -n to n. 
     // Second index is the maximum position so far, from 0 to n. 
     // Value is probability. 
     vector< vector<double> > _p; 
    }; 

    void go(int ds) 
     { 
     // Read n, l, r 
     int n, nds; 
     double l, r; 
     cin >> nds >> n >> l >> r; 
     const double c = 1 - l - r; 

     if(nds != ds){ 
      cout << "Dataset number " << nds << " does not match " << ds << endl; 
      return; 
     } 

     // Initialize state, probability 1 at (0,0) 
     State s(n); 
     s(0,0) = 1; 

     State t(n); 

     State* p1 = &s; 
     State* p2 = &t; 

     for (int k = 1; k <= n; ++k) 
      { 
      // Compute probabilities at step k 

      p2->zero(k); 

      // At step k, the farthest from the origin you can be is k 
      for (int i = -k; i <= k; ++i) 
      { 
       const int mm = State::min(State::max(0, i+k), k); 
      for (int m = 0; m <= mm; ++m) 
       { 
       // At step k-1, p = probability of (i,m) 
       const double p = p1->operator()(i,m); 
       if (p > 0) 
        { 
        // Step left 
        p2->operator()(i-1, m) += p*l; 
        // Step right 
        p2->operator()(i+1, State::max(i+1,m)) += p*r; 
        // Stay put 
        p2->operator()(i, m) += p*c; 
        } 
       } 
      } 
      swap(p1, p2); 
      } 

     // Compute expected maximum position 
     double p = 0; 
     for (int i = -n; i <= n; ++i) 
      for (int m = 0; m <= n; ++m) 
      p += m * p1->operator()(i,m); 

     printf("%d %0.4f\n", ds, p); 
     } 

    int main(int argc, char* argv[]) 
     { 
     // Read number of data sets to process 
     int num; 
     cin >> num; 

     // Process each data set identically 
     for (int i = 1; i <= num; ++i) 
      go(i); 

     // We're done 
     return 0; 
     } 

回答

6

你混淆了一個初始化state::operator()(int, int)通話。該運算符調用可讓您設置類實例元素的值。

State s(n); // this is the only initialization 
s(0,0) = 1; // this calls operator()(int, int) on instance s 
+0

啊我明白了,非常有趣。 = 1在做什麼? – 2013-03-12 14:26:10

+0

@JoshHorowitz基本上,操作員可以讓你訪問's'中的元素。因此,(0,0)= 1'將'1'的值賦給位置爲'0,0'的元素。把它想象成一種二維數組或矩陣。 – juanchopanza 2013-03-12 14:36:31

+0

啊,我明白了。非常感謝你 – 2013-03-12 14:53:38

0

在這一行:

s(0,0) = 1; 

它調用此:

double& operator()(int i, int m) 

而且因爲它返回到雙參考,可以分配給它。

0

第二行不再初始化。的構造是在第1行調用時,第二行調用

雙&運算符()(INT I,INT米)

,其中n = 0和m = 0和1寫入參考這是返回。

0

這一部分:

State(int n) : _n(n), _p(2*n+1) 

...是一個成員初始化列表。這有點類似,如果你寫的結構喜歡:

state(int n) { _n = n; _p = 2*n+1; } 

...但它初始化_n_p,而不是與他們開始未初始化,然後將它們分配值。在這個特定情況下,這可能沒有多大區別,但是當你有像只能被初始化(未分配)的引用時,它就變得至關重要。

s(0,0) = 1看起來像s打算有點像2D數組,它們已經重載了operator()作爲該數組的下標操作符。我發佈了一個在previous answer中這樣做的課程。