3 #include <wordring/trie/list_trie_iterator.hpp>
4 #include <wordring/trie/trie_base_iterator.hpp>
5 #include <wordring/trie/trie_construct_iterator.hpp>
6 #include <wordring/trie/trie_heap.hpp>
17 #include <type_traits>
63 template <
typename Allocator = std::allocator<trie_node>>
66 template <
typename Allocator1>
69 template <
typename Allocator1>
75 using typename base_type::container;
77 using typename base_type::index_type;
80 using base_type::null_value;
83 using label_type =
typename base_type::label_type;
84 using value_type = std::uint32_t;
85 using size_type =
typename container::size_type;
86 using allocator_type = Allocator;
101 using base_type::limit;
108 using base_type::add;
110 using base_type::m_c;
140 template <typename InputIterator, typename std::enable_if_t<std::is_integral_v<typename std::iterator_traits<InputIterator>::value_type>, std::nullptr_t> =
nullptr>
141 trie_base(InputIterator first, InputIterator last, allocator_type
const& alloc = allocator_type())
156 template <typename ForwardIterator, typename std::enable_if_t<std::negation_v<std::is_integral<typename std::iterator_traits<ForwardIterator>::value_type>>, std::nullptr_t> =
nullptr>
157 trie_base(ForwardIterator first, ForwardIterator last, allocator_type
const& alloc = allocator_type())
170 trie_base(std::initializer_list<trie_node> il, allocator_type
const& alloc = allocator_type())
187 template <typename InputIterator, typename std::enable_if_t<std::is_integral_v<typename std::iterator_traits<InputIterator>::value_type>, std::nullptr_t> =
nullptr>
188 void assign(InputIterator first, InputIterator last)
202 template <typename ForwardIterator, typename std::enable_if_t<std::negation_v<std::is_integral<typename std::iterator_traits<ForwardIterator>::value_type>>, std::nullptr_t> =
nullptr>
203 void assign(ForwardIterator first, ForwardIterator last)
205 using iterator_category =
typename std::iterator_traits<ForwardIterator>::iterator_category;
208 std::is_same_v<iterator_category, std::forward_iterator_tag>
209 || std::is_same_v<iterator_category, std::bidirectional_iterator_tag>
210 || std::is_same_v<iterator_category, std::random_access_iterator_tag>);
214 if (!std::is_sorted(first, last) || std::adjacent_find(first, last) != last)
216 while (first != last)
227 auto li = list_iterator(first, last);
228 auto it = construct_iterator(li);
230 while (!it.empty() && !it.children().empty())
232 auto view = it.parent();
233 auto it1 =
lookup(view.first, view.second);
234 if (it1.first.m_index == 0) it1.first.m_index = 1;
235 add(it1.first.m_index, it.children());
239 m_c.front().m_base = std::distance(first, last);
261 index_type base = (d + pos.m_index)->m_base;
262 index_type idx = (base <= 0)
295 template <
typename InputIterator>
298 auto it =
find(first, last);
299 if (it ==
cend())
throw std::out_of_range(
"");
303 index_type base = (d + it.m_index)->m_base;
304 index_type idx = (base <= 0)
320 template <
typename InputIterator>
321 const_reference
at(InputIterator first, InputIterator last)
const
323 return const_cast<trie_base*
>(
this)->
at(first, last);
338 template <
typename Key>
341 return at(std::begin(key), std::end(key));
354 template <
typename Key>
355 const_reference
const at(Key
const& key)
const
357 return at(std::begin(key), std::end(key));
370 template <
typename Key>
378 index_type base = (d + it.m_index)->m_base;
379 index_type idx = (base <= 0)
434 size_type
size() const noexcept {
return m_c.front().m_base; }
442 return std::numeric_limits<std::int32_t>::max() /
sizeof(
node_type);
457 template <
typename InputIterator>
460 assert(value <=
static_cast<value_type
>(std::numeric_limits<int32_t>::max()));
462 if (first == last)
return cend();
464 index_type parent = 1;
467 for (index_type idx =
at(parent,
static_cast<std::uint8_t
>(*first)); idx != 0; idx =
at(parent,
static_cast<std::uint8_t
>(*first)))
471 if (first == last)
break;
473 if (first != last) ++m_c.front().m_base;
478 if (first == last && !
has_null(parent))
480 index_type base = add(parent, null_value);
481 assert((m_c.data() + base + null_value)->m_base == 0);
482 (m_c.data() + base + null_value)->m_base = -
static_cast<index_type
>(value);
483 ++m_c.front().m_base;
486 else if (parent != 1 && !
has_null(parent) && first != last)
488 index_type val = (m_c.data() + parent)->m_base;
490 index_type base = add(parent, null_value);
491 assert((m_c.data() + base + null_value)->m_base == 0);
492 (m_c.data() + base + null_value)->m_base = val;
497 while (first != last)
499 std::uint16_t label =
static_cast<std::uint8_t
>(*first);
501 base = add(parent, label);
502 parent = base + label;
506 assert((m_c.data() + parent)->m_base == 0);
507 (m_c.data() + parent)->m_base = -
static_cast<index_type
>(value);
524 template <
typename Key>
527 return insert(std::begin(key), std::end(key), value);
538 index_type idx = pos.m_index;
539 assert(0 <= idx && idx < limit());
541 if (idx <= 1 || !
is_tail(idx))
return;
547 index_type i = (m_c.data() + idx)->m_base + null_value;
548 assert((m_c.data() + i)->m_check == idx);
551 if (!
has_child(idx)) (m_c.data() + idx)->m_base = 0;
556 index_type parent = 0;
557 if (!
has_sibling(idx)) parent = (m_c.data() + idx)->m_check;
558 assert(0 <= parent && parent < limit());
560 if (idx != 1)
free(idx);
561 if (parent == 0)
break;
566 --m_c.front().m_base;
577 template <
typename InputIterator>
578 void erase(InputIterator first, InputIterator last)
589 template <
typename Key>
592 erase(std::begin(key), std::end(key));
597 base_type::swap(other);
617 template <
typename InputIterator>
618 auto lookup(InputIterator first, InputIterator last, std::uint32_t& i)
const
622 index_type parent = 1;
624 while (first != last)
626 std::uint16_t ch =
static_cast<std::uint8_t
>(*first);
627 index_type idx =
at(parent, ch);
632 assert(1 <= parent && parent < limit());
648 template <
typename InputIterator>
649 auto lookup(InputIterator first, InputIterator last)
const
652 return lookup(first, last, i);
663 template <
typename InputIterator>
666 auto pair =
lookup(first, last);
668 return (pair.second == last)
681 template <
typename Key>
684 return search(std::begin(key), std::end(key));
696 template <
typename InputIterator>
699 auto pair =
lookup(first, last);
701 auto it = pair.second;
702 index_type idx = pair.first.m_index;
704 return (it == last &&
is_tail(idx))
717 template <
typename Key>
720 return find(std::begin(key), std::end(key));
730 template <
typename InputIterator>
731 bool contains(InputIterator first, InputIterator last)
const
733 auto pair =
lookup(first, last);
735 auto it = pair.second;
736 index_type idx = pair.first.m_index;
738 return !(it != last || !
is_tail(idx));
747 template <
typename Key>
750 return contains(std::begin(key), std::end(key));
758 template <
typename Allocator1>
769 template <
typename Allocator1>
const_reference at(const_iterator pos) const
葉の値への参照を返す
Definition: trie_base.hpp:277
trie_base(std::initializer_list< trie_node > il, allocator_type const &alloc=allocator_type())
初期化子リストからの構築
Definition: trie_base.hpp:170
const_iterator search(InputIterator first, InputIterator last) const
前方一致検索
Definition: trie_base.hpp:664
size_type size() const noexcept
格納しているキー文字列数を調べる
Definition: trie_base.hpp:434
bool has_null(index_type parent) const
Definition: trie_heap.hpp:690
trie_base(InputIterator first, InputIterator last, allocator_type const &alloc=allocator_type())
直列化データからの構築
Definition: trie_base.hpp:141
index_type free(index_type idx, index_type before=0)
Definition: trie_heap.hpp:526
void erase(InputIterator first, InputIterator last)
キー文字列を削除する
Definition: trie_base.hpp:578
bool is_tail(index_type idx) const
Definition: trie_heap.hpp:651
trie_base()
空のコンテナを構築する
Definition: trie_base.hpp:115
const_iterator cend() const noexcept
根の終端を指すイテレータを返す
Definition: trie_base.hpp:420
const_iterator insert(Key const &key, value_type value=0)
キー文字列を挿入する
Definition: trie_base.hpp:525
reference at(Key const &key)
葉の値への参照を返す
Definition: trie_base.hpp:339
friend std::istream & operator>>(std::istream &, trie_base< Allocator1 > &)
ストリームから入力する
Definition: trie_base.hpp:770
bool has_child(index_type parent) const
Definition: trie_heap.hpp:664
Definition: trie_base_iterator.hpp:8
trie_base(ForwardIterator first, ForwardIterator last, allocator_type const &alloc=allocator_type())
文字列リストからの構築
Definition: trie_base.hpp:157
basic_trie< Label, detail::trie_base< Allocator > > trie
メモリー使用量削減を目標とする汎用Trie
Definition: trie.hpp:1026
void erase(const_iterator pos)
キー文字列を削除する
Definition: trie_base.hpp:536
Definition: trie_construct_iterator.hpp:16
std::ostream & operator<<(std::ostream &os, stable_trie_base< Allocator1 > const &trie)
ストリームへ出力する
Definition: stable_trie_base.hpp:752
const const_reference at(Key const &key) const
葉の値への参照を返す
Definition: trie_base.hpp:355
reference operator[](Key const &key)
葉の値への参照を返す
Definition: trie_base.hpp:371
const_reference at(InputIterator first, InputIterator last) const
葉の値への参照を返す
Definition: trie_base.hpp:321
reference at(const_iterator pos)
葉の値への参照を返す
Definition: trie_base.hpp:257
void assign(InputIterator first, InputIterator last)
直列化データから割り当てる
Definition: trie_heap.hpp:260
const_iterator insert(InputIterator first, InputIterator last, value_type value=0)
キー文字列を挿入する
Definition: trie_base.hpp:458
trie_base(allocator_type const &alloc)
アロケータを指定して空のコンテナを構築する
Definition: trie_base.hpp:124
const_iterator end() const noexcept
根の終端を指すイテレータを返す
Definition: trie_base.hpp:411
void clear() noexcept
すべての要素を削除する
Definition: trie_heap.hpp:364
const_iterator begin() const noexcept
根を指すイテレータを返す
Definition: trie_base.hpp:394
文字列の集合をTrie構築に適した形で走査するイテレータ
Definition: list_trie_iterator.hpp:20
const_iterator search(Key const &key) const
前方一致検索
Definition: trie_base.hpp:682
任意の整数型をラベルとして用いることが出来る汎用Trie
Definition: trie.hpp:130
const_iterator find(InputIterator first, InputIterator last) const
完全一致検索
Definition: trie_base.hpp:697
allocator_type get_allocator() const
コンテナに関連付けられているアロケータを返す
Definition: trie_heap.hpp:226
const_iterator cbegin() const noexcept
根を指すイテレータを返す
Definition: trie_base.hpp:402
Definition: trie_heap.hpp:23
auto lookup(InputIterator first, InputIterator last) const
部分一致検索
Definition: trie_base.hpp:649
static constexpr size_type max_size() noexcept
キー文字列の格納可能な最大数を調べる
Definition: trie_base.hpp:440
bool empty() const noexcept
キー文字列を格納していないことを調べる
Definition: trie_base.hpp:428
serialize_iterator ibegin() const
直列化用のイテレータを返す
Definition: trie_heap.hpp:342
void assign(InputIterator first, InputIterator last)
直列化データからの割り当て
Definition: trie_base.hpp:188
reference at(InputIterator first, InputIterator last)
葉の値への参照を返す
Definition: trie_base.hpp:296
ダブル・アレイによるTrie実装のメモリー管理を行う
Definition: trie_heap.hpp:200
index_type at(index_type parent, std::uint16_t label) const
Definition: trie_heap.hpp:766
終端の空遷移を併合したTrie木の実装
Definition: trie_base.hpp:64
bool has_sibling(index_type idx) const
Definition: trie_heap.hpp:710
const_iterator find(Key const &key) const
完全一致検索
Definition: trie_base.hpp:718
bool contains(InputIterator first, InputIterator last) const
キー文字列が格納されているか調べる
Definition: trie_base.hpp:731
Definition: trie_heap.hpp:40
void assign(ForwardIterator first, ForwardIterator last)
文字列リストからの割り当て
Definition: trie_base.hpp:203
void erase(Key const &key)
キー文字列を削除する
Definition: trie_base.hpp:590
bool contains(Key const &key) const
キー文字列が格納されているか調べる
Definition: trie_base.hpp:748
serialize_iterator iend() const
直列化用のイテレータを返す
Definition: trie_heap.hpp:353
auto lookup(InputIterator first, InputIterator last, std::uint32_t &i) const
部分一致検索
Definition: trie_base.hpp:618
std::istream & operator>>(std::istream &is, stable_trie_base< Allocator1 > &trie)
ストリームから入力する
Definition: stable_trie_base.hpp:763
friend std::ostream & operator<<(std::ostream &, trie_base< Allocator1 > const &)
ストリームへ出力する
Definition: trie_base.hpp:759
Definition: trie_heap.hpp:78