cp-library

C++ Library for Competitive Programming

View the Project on GitHub emthrm/cp-library

:heavy_check_mark: トライ木 (trie)
(include/emthrm/string/trie.hpp)

複数の文字列を高速に検索できる木である。

時間計算量

$O(\lvert S \rvert)$

仕様

template <int Sigma = 26>
struct Trie;

メンバ変数

名前 説明
const std::function<int(const char)> convert 文字を数に変換する関数
std::vector<Node> nodes トライ木の頂点

メンバ関数

名前 効果・戻り値  
explicit Trie(const std::function<int(const char)> convert = [](const char c) -> int { return c - 'a'; }); コンストラクタ  
void add(const std::string& s, const int id = -1, int pos = 0); $\mathrm{pos}$ 番目のノードから ID $\mathrm{id}$ の文字列 $S$ を追加する。  
int find(const std::string& t, int pos = 0) const; $\mathrm{pos}$ 番目のノードから見たとき、文字列 $T$ に対応するノードのインデックス。ただし存在しないときは $-1$ を返す。  

メンバ型

名前 説明
Node ノードを表す構造体
struct Node

メンバ変数

名前 説明
char c そのノードが表す文字
std::array<int, Sigma> nxt 子のインデックス
std::vector<int> tails そのノードを末尾とする文字列の ID 集合

メンバ関数

名前 効果
explicit Node(const char c); コンストラクタ

参考文献

TODO

Submissons

https://yukicoder.me/submissions/413744

Required by

Verified with

Code

#ifndef EMTHRM_STRING_TRIE_HPP_
#define EMTHRM_STRING_TRIE_HPP_

#include <algorithm>
#include <array>
#include <functional>
#include <string>
#include <vector>

namespace emthrm {

template <int Sigma = 26>
struct Trie {
  struct Node {
    char c;
    std::array<int, Sigma> nxt;
    std::vector<int> tails;

    explicit Node(const char c) : c(c) {
      std::fill(nxt.begin(), nxt.end(), -1);
    }
  };

  const std::function<int(const char)> convert;
  std::vector<Node> nodes;

  explicit Trie(const std::function<int(const char)> convert =
                    [](const char c) -> int { return c - 'a'; })
      : convert(convert) { nodes.emplace_back('$'); }

  void add(const std::string& s, const int id = -1, int pos = 0) {
    for (const char c : s) {
      const int c_int = convert(c);
      if (nodes[pos].nxt[c_int] == -1) {
        const int nxt_pos = nodes.size();
        nodes[pos].nxt[c_int] = nxt_pos;
        nodes.emplace_back(c);
        pos = nxt_pos;
      } else {
        pos = nodes[pos].nxt[c_int];
      }
    }
    nodes[pos].tails.emplace_back(id);
  }

  int find(const std::string& t, int pos = 0) const {
    for (const char c : t) {
      const int c_int = convert(c);
      if (nodes[pos].nxt[c_int] == -1) return -1;
      pos = nodes[pos].nxt[c_int];
    }
    return pos;
  }
};

}  // namespace emthrm

#endif  // EMTHRM_STRING_TRIE_HPP_
#line 1 "include/emthrm/string/trie.hpp"



#include <algorithm>
#include <array>
#include <functional>
#include <string>
#include <vector>

namespace emthrm {

template <int Sigma = 26>
struct Trie {
  struct Node {
    char c;
    std::array<int, Sigma> nxt;
    std::vector<int> tails;

    explicit Node(const char c) : c(c) {
      std::fill(nxt.begin(), nxt.end(), -1);
    }
  };

  const std::function<int(const char)> convert;
  std::vector<Node> nodes;

  explicit Trie(const std::function<int(const char)> convert =
                    [](const char c) -> int { return c - 'a'; })
      : convert(convert) { nodes.emplace_back('$'); }

  void add(const std::string& s, const int id = -1, int pos = 0) {
    for (const char c : s) {
      const int c_int = convert(c);
      if (nodes[pos].nxt[c_int] == -1) {
        const int nxt_pos = nodes.size();
        nodes[pos].nxt[c_int] = nxt_pos;
        nodes.emplace_back(c);
        pos = nxt_pos;
      } else {
        pos = nodes[pos].nxt[c_int];
      }
    }
    nodes[pos].tails.emplace_back(id);
  }

  int find(const std::string& t, int pos = 0) const {
    for (const char c : t) {
      const int c_int = convert(c);
      if (nodes[pos].nxt[c_int] == -1) return -1;
      pos = nodes[pos].nxt[c_int];
    }
    return pos;
  }
};

}  // namespace emthrm
Back to top page