This repository was archived by the owner on Dec 20, 2021. It is now read-only.
This repository was archived by the owner on Dec 20, 2021. It is now read-only.
Trieっぽい何か #2
Open
Description
現状とりあえず仮組みしただけって感じなので変数名とかがメチャクチャ適当ですが…
class EmojiData
{
private:
struct trie{
std::unique_ptr<std::unordered_map<std::uint32_t, trie>> nexts;
std::size_t t;
};
/* データセット (約 2000 種類の絵文字の codePoint 一覧) */
const trie emojiCodePoints =
[]{
trie t = {std::make_unique<std::unordered_map<std::uint32_t, trie>>(), 0};
const std::vector<std::vector<std::uint32_t>> vec = {
#include "EmojiCodePoints.txt"
};
trie* p;
for(std::vector<std::uint32_t>::size_type j = 0; j != vec.size(); ++j){
p = &t;
for(std::vector<std::uint32_t>::size_type i = 0; i != vec[j].size(); ++i){
if(!p->nexts)
p->nexts = std::make_unique<std::unordered_map<std::uint32_t, trie>>();
p = &(*p->nexts)[vec[j][i]];
}
p->t = vec[j].size();
}
return std::move(t);
}();
public:
EmojiData() = default;
size_t check(std::vector<std::uint32_t>::const_iterator beg, std::vector<std::uint32_t>::const_iterator end)const
{
const trie* t = &emojiCodePoints;
while(true){
if(!t->nexts || beg == end)
return std::size_t{t->t};
auto it = t->nexts->find(*beg++);
if(it == t->nexts->end())
return std::size_t{t->t};
t = &it->second;
}
return /**/0;
}
};
- メモリ効率はあんまり良くないと思います.サイズもそうですが,
unique_ptr
とunorderd_map
を組み合わせてるので断片化が激しそう…- バケットサイズとか指定すると多少は改善するかもしれないのでちょっといじります
- 速度は速いです
- 素直な実装(
std::vector<std::vector<std::uint32_t>>
を要素数で降順ソートかけたやつを上から総なめする)に比べると20倍ぐらい速い.初期化は3倍ぐらい遅いけど,使い方によっては誤差かなと思います.
- 素直な実装(
Metadata
Metadata
Assignees
Labels
No labels