Skip to content
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
Open
@wx257osn2

Description

@wx257osn2

現状とりあえず仮組みしただけって感じなので変数名とかがメチャクチャ適当ですが…

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_ptrunorderd_mapを組み合わせてるので断片化が激しそう…
    • バケットサイズとか指定すると多少は改善するかもしれないのでちょっといじります
  • 速度は速いです
    • 素直な実装(std::vector<std::vector<std::uint32_t>>を要素数で降順ソートかけたやつを上から総なめする)に比べると20倍ぐらい速い.初期化は3倍ぐらい遅いけど,使い方によっては誤差かなと思います.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions