【问题标题】:Generic Segment Tree implementation using C++ Templates使用 C++ 模板的通用段树实现
【发布时间】:2013-06-25 08:52:00
【问题描述】:

我正在尝试为更新和范围查询创建一个通用的段树类。

我不想假设元素只是整数并且要对一系列元素进行的操作是它们的总和或乘积,我希望用户提供元素的类型 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);
        }
};

当我尝试使用这个类时,结果发现我作为参数传入的 compose 函数没有被使用,相反,来自 class binary_function_unitype 的那个 正在使用中。

我希望用户的函数定义会覆盖 class binary_function_unitype 中的函数定义,这样我的工作就完成了。但那并没有发生。使用该类的程序如下:

#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;
}

谁能告诉我我的方法有什么缺陷,或者我是否误解了在 C++ 中使用继承或模板的一些基本概念?

谢谢。

【问题讨论】:

    标签: c++ templates inheritance functor segment-tree


    【解决方案1】:

    构造函数通过值获取binary_function_unitype,因此它将slice

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多