⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prefixtree.h.svn-base

📁 moses开源的机器翻译系统
💻 SVN-BASE
字号:
// $Id$/* ---------------------------------------------------------------- *//* Copyright 2005 (c) by RWTH Aachen - Lehrstuhl fuer Informatik VI *//* Richard Zens                                                     *//* ---------------------------------------------------------------- */#ifndef PREFIXTREE_H_#define PREFIXTREE_H_#include <vector>#include <algorithm>#include <cassert>#include <deque>#include "Util.h"#include "FilePtr.h"#include "File.h"template<typename T,typename D>class PrefixTreeSA {public:  typedef T Key;  typedef D Data;  typedef PrefixTreeSA<T,D> Self;  typedef std::vector<T> VT;  typedef std::vector<Self*> VP;  typedef std::vector<D> VD;  VT keys;  VP ptr;  VD data;  static Data def;public:  PrefixTreeSA() {}  ~PrefixTreeSA() {for(size_t i=0;i<ptr.size();++i) delete ptr[i];}  static const Data& getDefault() {return def;}  static void setDefault(const Data& x) {def=x;}  // insert sequence  template<typename fwiter> Data& insert(fwiter b,fwiter e) {    typename VT::iterator i=std::lower_bound(keys.begin(),keys.end(),*b);    typename VT::iterator kb=keys.begin();    size_t pos=std::distance(kb,i);    if(i==keys.end() || *i!=*b) {      keys.insert(i,*b);      data.insert(data.begin()+pos,def);      ptr.insert(ptr.begin()+pos,0);    }    if(++b!=e) {      if(!ptr[pos]) ptr[pos]=new Self;      return ptr[pos]->insert(b,e);    }    else return data[pos];  }  // insert container  template<typename cont> Data& insert(const cont& c) {    return insert(c.begin(),c.end());}  size_t size() const {return keys.size();}  const Key& getKey(size_t i) const {return keys[i];}  const Data& getData(size_t i) const {return data[i];}  const Self* getPtr(size_t i) const {return ptr[i];}  size_t findKey(const Key& k) const {    typename VT::const_iterator i=std::lower_bound(keys.begin(),keys.end(),k);    if(i==keys.end() || *i!=k) return keys.size();    return std::distance(keys.begin(),i);  }  // find sequence  template<typename fwiter> const Data* findPtr(fwiter b,fwiter e) const {    size_t pos=findKey(*b);    if(pos==keys.size()) return 0;    if(++b==e) return &data[pos];    if(ptr[pos]) return ptr[pos]->findPtr(b,e); else return 0;  }  // find container  template<typename cont> const Data* findPtr(const cont& c) const {    return findPtr(c.begin(),c.end());}  // find sequence  template<typename fwiter> const Data& find(fwiter b,fwiter e) const {    if(const Data* p=findPtr(b,e)) return *p; else return def;  }  // find container  template<typename cont> const Data& find(const cont& c) const {    return find(c.begin(),c.end());}  void shrink() {    ShrinkToFit(keys); ShrinkToFit(ptr); ShrinkToFit(data);}};template<typename T,typename D> D PrefixTreeSA<T,D>::def;/////////////////////////////////////////////////////////////////////////////template<typename T,typename D>class PrefixTreeF {public:  typedef T Key;  typedef D Data;private:  typedef PrefixTreeF<Key,Data> Self;public:  typedef FilePtr<Self> Ptr;private:  typedef std::vector<Key> VK;  typedef std::vector<Data> VD;  typedef std::vector<Ptr> VP;  VK keys;  VD data;  VP ptr;  static Data def;  OFF_T startPos;  FILE* f;public:  PrefixTreeF(FILE* f_=0) : f(f_) {if(f) read();}  ~PrefixTreeF() {free();}  void read() {    startPos=fTell(f);    fReadVector(f,keys);    fReadVector(f,data);    ptr.clear();ptr.resize(keys.size());    std::vector<OFF_T> rawOffs(keys.size());    fread(&rawOffs[0], sizeof(OFF_T), keys.size(), f);    for(size_t i=0;i<ptr.size();++i)      if (rawOffs[i]) ptr[i].set(f, rawOffs[i]);  }				        void free() {    for(typename VP::iterator i=ptr.begin();i!=ptr.end();++i) i->free();}  void reserve(size_t s) {    keys.reserve(s);data.reserve(s);ptr.reserve(s);}  template<typename fwiter>  void changeData(fwiter b,fwiter e,const Data& d) {    typename VK::const_iterator i=std::lower_bound(keys.begin(),keys.end(),*b);    if(i==keys.end() || *i!=*b) {      TRACE_ERR("ERROR: key not found in changeData!\n"); return;}    typename VK::const_iterator kb=keys.begin();    size_t pos=std::distance(kb,i);    if(++b==e) {      OFF_T p=startPos+keys.size()*sizeof(Key)+2*sizeof(unsigned)+pos*sizeof(Data);      TRACE_ERR("elem found at pos "<<p<<" old val: "<<data[pos]<<"  startpos: "<<startPos<<"\n");      if(data[pos]!=d) {        data[pos]=d;fSeek(f,p);fWrite(f,d);}      return;    }    if(ptr[pos]) ptr[pos]->changeData(b,e,d); else {      TRACE_ERR("ERROR: seg not found!in changeData\n");    }  }  void create(const PrefixTreeSA<Key,Data>& psa,const std::string& fname) {    FILE* f=fOpen(fname.c_str(),"wb");    create(psa,f);    fclose(f);  }  void create(const PrefixTreeSA<Key,Data>& psa,FILE* f,int verbose=0) {    setDefault(psa.getDefault());    typedef std::pair<const PrefixTreeSA<Key,Data>*,OFF_T> P;    typedef std::deque<P> Queue;    Queue queue;    queue.push_back(P(&psa,fTell(f)));    bool isFirst=1;    size_t ns=1;    while(queue.size()) {      if(verbose && queue.size()>ns) {        TRACE_ERR("stack size in PF create: "<<queue.size()<<"\n");        while(ns<queue.size()) ns*=2;}      const P& pp=queue.back();      const PrefixTreeSA<Key,Data>& p=*pp.first;      OFF_T pos=pp.second;      queue.pop_back();      if(!isFirst) {        OFF_T curr=fTell(f);        fSeek(f,pos);        fWrite(f,curr);        fSeek(f,curr);      } else isFirst=0;      size_t s=0;      s+=fWriteVector(f,p.keys);      s+=fWriteVector(f,p.data);      for(size_t i=0;i<p.ptr.size();++i) {        if(p.ptr[i])          queue.push_back(P(p.ptr[i],fTell(f)));        OFF_T ppos=0;        s+=fWrite(f,ppos);      }    }  }  size_t size() const {return keys.size();}  const Key& getKey(size_t i) const {return keys[i];}  const Data& getData(size_t i) const {return data[i];}  const Self* getPtr(size_t i) const {return ptr[i];}  size_t findKey(const Key& k) const {    typename VK::const_iterator i=std::lower_bound(keys.begin(),keys.end(),k);    if(i==keys.end() || *i!=k) return keys.size();    return std::distance(keys.begin(),i);  }  Ptr const* findKeyPtr(const Key& k) const {    size_t pos=findKey(k);		return (pos<keys.size() ? &ptr[pos] : 0);  }  // find sequence  template<typename fwiter> const Data* findPtr(fwiter b,fwiter e) const {    typename VK::const_iterator i=std::lower_bound(keys.begin(),keys.end(),*b);    if(i==keys.end() || *i!=*b) return 0;    size_t pos=std::distance(keys.begin(),i);    if(++b==e) return &data[pos];    if(ptr[pos]) return ptr[pos]->findPtr(b,e); else return 0;  }  // find container  template<typename cont> const Data* findPtr(const cont& c) const {    return findPtr(c.begin(),c.end());}  // find sequence  template<typename fwiter> const Data& find(fwiter b,fwiter e) const {    if(const Data* p=findPtr(b,e)) return *p; else return def;} //return (p?*p:def);}  // find container  template<typename cont> const Data& find(const cont& c) const {    return find(c.begin(),c.end());}  static void setDefault(const Data& d) {def=d;}  static const Data& getDefault() {return def;}  void print(std::ostream& out,const std::string s="") const {    out<<s<<"startpos: "<<startPos<<"  size: "<<keys.size()<<"\n";    for(size_t i=0;i<keys.size();++i) {      out<<s<<i<<" - "<<keys[i]<<" "<<data[i]<<"\n";    }    for(size_t i=0;i<ptr.size();++i)      if(ptr[i])        ptr[i]->print(out,s+"  ");  }};template<typename T,typename D> D PrefixTreeF<T,D>::def;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -