libUTL++
BoyerMooreSearch.h
1 #pragma once
2 
4 
5 #include <libutl/Object.h>
6 
8 
9 UTL_NS_BEGIN;
10 
12 
28 
30 template <class T = char>
31 class BoyerMooreSearch : public Object, protected FlagsMI
32 {
34 
35 public:
43  BoyerMooreSearch(bool owner, const T* pat, size_t patLen, uint_t A = uint_t_max)
44  {
45  init(A);
46  set(owner, pat, patLen);
47  }
48 
55  const T* find(const T* str, size_t strLen) const;
56 
63  void set(bool owner, const T* pat, size_t patLen);
64 
66  size_t
67  length() const
68  {
69  return _patLen;
70  }
71 
73  bool
74  isOwner() const
75  {
76  return getFlag(flg_owner);
77  }
78 
80  void
81  setOwner(bool owner)
82  {
83  setFlag(flg_owner, owner);
84  }
85 
86 private:
87  enum flg_t
88  {
89  flg_owner
90  };
91 
92 private:
93  void init(uint_t A = uint_t_max);
94  void
95  deInit()
96  {
97  if (isOwner()) delete[] _pat;
98  delete[] _skip;
99  }
100 
101 private:
102  const T* _pat;
103  size_t _patLen;
104  ushort_t* _skip;
105  uint_t _A;
106 };
107 
109 
110 template <class T>
111 const T*
112 BoyerMooreSearch<T>::find(const T* str, size_t strLen) const
113 {
114  // minimize this-> overhead
115  const T* pat = _pat;
116  size_t patLen = _patLen;
117  const ushort_t* skip = _skip;
118 
119  // the actual search
120  const T* strPtr = str + patLen - 1;
121  const T* strEnd = str + strLen;
122  while (strPtr < strEnd)
123  {
124  const T* patPtr = pat + patLen - 1;
125  while (*patPtr == *strPtr)
126  {
127  if (patPtr == pat) return strPtr;
128  --patPtr;
129  --strPtr;
130  }
131 
132  strPtr += max(skip[(uint64_t)*strPtr], (ushort_t)(patLen - (patPtr - pat)));
133  }
134 
135  return nullptr;
136 }
137 
139 
140 template <class T>
141 void
142 BoyerMooreSearch<T>::set(bool owner, const T* pat, size_t patLen)
143 {
144  if (isOwner()) delete[] _pat;
145  setOwner(owner);
146  _pat = pat;
147  _patLen = patLen;
148 
149  // set up the skip table
150  size_t i;
151  uint_t A = _A;
152  ushort_t* skip = _skip;
153  for (i = 0; i < A; i++)
154  {
155  skip[i] = patLen;
156  }
157  for (i = 0; i < patLen; i++)
158  {
159  skip[(uint64_t)pat[i]] = patLen - 1 - i;
160  }
161 }
162 
164 
165 template <class T>
166 void
168 {
169  if (A == uint_t_max)
170  {
172  }
173  _A = A;
174  _pat = nullptr;
175  _skip = new ushort_t[A];
176 }
177 
179 
180 template <class T>
181 const T*
182 boyerMooreSearch(const T* str, size_t strLen, const T* pat, size_t patLen)
183 {
184  return BoyerMooreSearch<T>(false, pat, patLen).find(str, strLen);
185 }
186 
188 
189 UTL_NS_END;
190 
192 
#define UTL_CLASS_IMPL_TPL(className, T)
Implementation of standard UTL++ functionality for a template class.
Definition: macros.h:906
void deInit()
De-initialize UTL++.
const T & max(const T &a, const T &b, const R &... args)
Return the largest value among two or more provided values of the same type.
Definition: util_inl.h:89
bool isOwner() const
Get the owner flag.
Mix-in to provide 64-bits for space-efficient storage of up to 64 boolean flags.
Definition: FlagsMI.h:25
unsigned long uint64_t
Unsigned 64-bit integer.
Definition: types.h:154
Boyer-Moore string search.
void setOwner(bool owner)
Get the owner flag.
unsigned int uint_t
Unsigned integer.
Definition: types.h:59
const uint_t uint_t_max
Maximum uint_t value.
unsigned short ushort_t
Unsigned short integer.
Definition: types.h:45
const T & min(const T &a, const T &b, const R &... args)
Return the smallest value among two or more provided values of the same type.
Definition: util_inl.h:61
#define UTL_CLASS_DECL_TPL(DC, T, BC)
Declaration of standard UTL++ functionality for a template class with one parameter.
Definition: macros.h:713
size_t length() const
Get the length of the pattern.
Root of UTL++ class hierarchy.
Definition: Object.h:52
void init()
Initialize UTL++.
BoyerMooreSearch(bool owner, const T *pat, size_t patLen, uint_t A=uint_t_max)
Constructor.