Vector的应用:带删除标记的vector

在正则表达式识别的过程中,需要同时跟踪多个正则表达式的识别状态。最自然的做法是用n个元素的指针数组同时跟踪n个识别路径。当输入的字符跟识别路径上接受的输入不符时,这一路的指针失效。当识别路径上遇到ε字符时,这一路的指针发生分叉。

STL的vector 能有效的进行自动管理内存,比较适合用来存储这种个数不确定的动态指针数组。为了最小化删除一个指针在数组内产生的移动开销,使用一个删除标记来管理失效的指针。

这是对STL的vector 改造后的实现:

#include <vector>

using namespace std;

template <class T>
struct item {
    
    
        T  value;
        int tag;
};

template <class T>
class myvector {
    
    
public:
        enum {
    
    TAG_OK, TAG_FREE};
        vector<item<T> > v;
        int max;

        myvector() {
    
    max=0;}
        T &operator[](int n) {
    
    
                if (n>=0 && n<max) {
    
    
                        return v[n].value;
                }
                throw "out of range error";
        }
        void append(T t) {
    
    
                int size;
                struct item<T>  tv;
                tv.value =t;
                tv.tag= TAG_OK;
                size = v.size();

                if (max <size) {
    
    
                        v[max]= tv;
                        max++;
                }
                else {
    
    
                        v.push_back(tv);
                        max++;
                }
        }


        class iterator;
        iterator end() {
    
    
                iterator i;
                i.v = &v;
                i.it = v.end();
                if (max <v.size()) {
    
    
                        i.it = typename vector<item<T> >::iterator(&v[max]);
                }
                return i;
        }

        iterator begin(){
    
    
                iterator i;
                i.v = &v;
                i.it = v.begin();
                while(i.it!=v.end() && (*i.it).tag ==TAG_FREE) {
    
    
                        ++i.it;
                }
                return i;
        }
        void pack() {
    
    
                int i;
                iterator it;
                i=0;
                it = begin();
                while(it!=end()) {
    
    
                        v[i++] = *(it.it);
                        ++it;
                }
                max =i;
                //v.resize(max);
        }

        class iterator  {
    
    
        public :
                typename vector<item<T> >::iterator it;
                vector<item<T> > *v;

                iterator(const iterator& itt): it(itt.it){
    
    v= itt.v;}
                iterator() {
    
    }
                iterator(vector<item<T> > *v,
                        const typename vector<item<T> >::iterator &it)
                        : v(v), it(it)
                        {
    
    }
                iterator &operator=(const iterator& itt) {
    
    
                        it = itt.it;
                        v = itt.v;
                        return *this;
                }
                iterator &operator++() {
    
    
                        if (it!= v->end()) {
    
    
                                ++it;
                                while(it!=v->end() && (*it).tag ==TAG_FREE) {
    
    
                                        ++it;
                                }
                        }
                        return *this;
                }
                T operator*() {
    
    
                        return (*it).value;
                }
                T* operator->() {
    
    
                        return &(it->value);
                }

                void del() {
    
    
                        it->tag=TAG_FREE;
                }

                bool operator != (const iterator & r) {
    
    
                        return it!= r.it;
                }
        };
};
 

iterator的del()操作,对vector里面的元素进行删除标记。删除后的元素,用[index]索引还能看到,但用iterator访问已经被屏蔽了。直到vector调用pack()操作,批量的把失效指针去掉。

下面是测试代码,用一个int 来代替指针:

int main()
{
    
    
        myvector<int> mv;

        int i;
        for(i=0; i<10; i++) mv.append(i+100);
        for(i=0; i<10;i++)  printf("%d ", mv[i]);
        printf("\n");

        myvector<int>::iterator it;

        it = mv.begin();
        while(it!= mv.end()) {
    
    
                printf("%d ", *it);
                ++it;
        }
        it = mv.begin();
        i=0;
        while(it!= mv.end()) {
    
    
                ++it;
                ++i;
                if ((i&1)==1) {
    
    
                        it.del();
                }
        }
        printf("\n");
        it = mv.begin();
        while(it!= mv.end()) {
    
    
                printf("%d ", *it);
                ++it;
        }
        printf("\n");

        vector<item<int> >::iterator index;
        item<int> val;
        index = mv.v.begin();
        while (index!=mv.v.end()) {
    
    
                val = *index;
                printf("%d(%d) ",val.value, val.tag);
                ++index;
        }
        printf("\n");

        mv.pack();
        index = mv.v.begin();
        while (index!=mv.v.end()) {
    
    
                val = *index;
                printf("%d(%d) ",val.value, val.tag);
                ++index;
        }
        printf("\n");

        return 0;
}

可以看到如下的运行结果,这正是所需要的。

100 101 102 103 104 105 106 107 108 109
100 101 102 103 104 105 106 107 108 109
100 102 104 106 108
100(0) 101(1) 102(0) 103(1) 104(0) 105(1) 106(0) 107(1) 108(0) 109(1)
100(0) 102(0) 104(0) 106(0) 108(0) 105(1) 106(0) 107(1) 108(0) 109(1)

猜你喜欢

转载自blog.csdn.net/aaasssdddd96/article/details/110135124