2013-06-25 3 views
0

업데이트 및 범위 쿼리를위한 일반 세그먼트 트리 클래스를 만들려고합니다.C++ 템플릿을 사용한 일반 세그먼트 트리 구현

대신 요소가 정수가되고 다양한 요소에 대해 수행 할 작업을 합이나 곱으로 가정하는 대신 사용자가 요소의 T 유형과 함수를 제공해야합니다. 나는 으로 명명했다.

이 함수는 T 타입의 매개 변수를 두 개 가져와 동일한 유형 T의 값을 반환합니다.이 반환 값은 동일한 작업을 수행하는 데 사용할 수있는 2 개의 요소 범위에서 원하는 연산을 수행 한 결과입니다 임의의 수의 요소 범위.

#include <functional> 

template<class T> 
class SegmentTree { 

    public: 
     class binary_function_unitype: public std::binary_function<T,T,T> { 
      public: 
       virtual T operator() (T arg1, T arg2) {}; 
     }; 

    private: 
     class Node { 
      public: 
       T value; 
       int seg_start, seg_end; 
       Node* left; 
       Node* right; 
       Node (T value, int seg_start, int seg_end, Node* left=0, Node* right=0) { 
        this->value = value; 
        this->seg_start = seg_start; 
        this->seg_end = seg_end; 
        this->left = left; 
        this->right = right; 
       } 
     }; 

     // Not expecting the compose function to be robust enough. 
     T composeUtil (T arg1, T arg2) { 
      if (arg1!=0 && arg2!=0) 
       return compose(arg1,arg2); 
      else if (arg1!=0) 
       return arg1; 
      else if (arg2!=0) 
       return arg2; 
     } 

     // Creating the Segment Tree. 
     Node* createTree (T leaves[], int start, int end) { 
      // base case - leaf of tree. 
      if (start==end) 
       return new Node(leaves[start],start,start,0,0); 
      // general case. 
      int mid = start + (end-start)/2; 
      Node* left = createTree(leaves,start,mid); 
      Node* right = createTree(leaves,mid+1,end); 
      T retValue = composeUtil(left->value,right->value); 
      return new Node(retValue,start,end,left,right); 
     } 

     // Range Query helper. 
     T queryUtil (Node* root, int start, int end) { 
      int seg_start = root->seg_start, seg_end = root->seg_end; 
      if (seg_start>end || seg_end<start) 
       return 0; 
      else if (seg_start>=start && seg_end<=end) 
       return root->value; 
      else 
       return compose(queryUtil(root->left,start,end), queryUtil(root->right,start,end)); 
     } 

     // Helper function for Updating the Segment Tree. 
     void updateUtil (Node* root, int position, T updatedValue) { 
      int seg_start = root->seg_start, seg_end = root->seg_end; 
      if(seg_start>position || seg_end<position) 
       return; 
      else if(seg_start==seg_end) 
       root->value = updatedValue; 
      else 
       root->value = composeUtil(root->left->value,root->right->value); 
     } 

     // Freeing the memory allocated to the Segment Tree. 
     void destroyTree(Node* root) { 
      if (root->left!=0) 
       destroyTree(root->left); 
      if (root->right!=0) 
       destroyTree(root->right); 
      delete root; 
     } 

     Node* root; 
     binary_function_unitype compose; 

    public: 
     SegmentTree (T leaves[], binary_function_unitype compose, int start, int end) { 
      this->compose = compose; 
      this->root = createTree(leaves, start, end); 
     } 

     T query (int start, int end) { 
      return queryUtil(root, start, end); 
     } 

     void update (int position, T updatedValue) { 
      updateUtil(root, position, updatedValue); 
     } 

     ~SegmentTree() { 
      destroyTree(root); 
     } 
}; 

나는이 클래스를 사용하려고는 반대로, 사용하지 않는 가 나는 paramater로했다 기능을 구성하는 것으로 밝혀 다음과 같이

클래스입니다 클래스의 binary_function_unitype이 사용되고 있습니다.

사용자의 함수 정의가 클래스 binary_function_unitype에있는 함수 정의를 무시하고 내 작업이 완료 될 것으로 예상했습니다. 그러나 그런 일은 일어나지 않았습니다. 내 접근 또는 경우 결함은 내가 C++에서 상속 또는 템플릿을 사용하는 방법에 대한 몇 가지 기본 개념을 오해 무슨

#include <iostream> 
#include "SegmentTree.h" 

using namespace std; 

class Compose: public SegmentTree<int>::binary_function_unitype { 
    public: 
     int operator() (int arg1, int arg2) { 
      return arg1+arg2; 
     } 
}; 

int main() 
{ 
    int num; 
    cin>>num; 
    int arr[num]; 
    for(int i=0;i<num;i++) 
     cin>>arr[i]; 
    Compose compose; 
    SegmentTree<int> segTree(arr, compose, 0, num-1); 
    int s,e; 
    cin>>s>>e; 
    cout<<segTree.query(s-1,e-1); 
    return 0; 
} 

누군가가 말해 줄래 다음과 같이이 클래스를 사용하는 프로그램은 무엇입니까?

감사합니다.

답변

0

생성자는 값만큼 binary_function_unitype 걸리므는 slice을 것이다.