#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
using namespace std;
constexpr size_t MAX_WORD_LEN = 20;
unordered_map<string, string> anagrams;
string get_sorted_word(const string& word)
{
auto sorted_word = word;
sort(sorted_word.begin(), sorted_word.end());
return sorted_word;
}
template<typename IteratorOfStrings>
void prepare_anagrams(IteratorOfStrings first, IteratorOfStrings last)
{
for (; first != last; ++first)
{
const std::string& word = *first;
anagrams.emplace(get_sorted_word(word), word);
}
}
unordered_map<size_t, bool> _check_cache;
bool _check(const string& sentence)
{
if (sentence.length() <= MAX_WORD_LEN and anagrams.find(get_sorted_word(sentence)) != anagrams.end())
return true;
size_t max_len = min(MAX_WORD_LEN, sentence.length());
for (size_t i = 1; i < max_len; ++i)
{
auto prefix = get_sorted_word(sentence.substr(0, i));
if (anagrams.find(prefix) == anagrams.end())
continue;
// Check cache.
auto it = _check_cache.find(i);
if (it != _check_cache.end())
{
if (it->second) return true;
else continue;
}
// Calculate from scratch.
auto sufix = sentence.substr(i);
bool result = _check(sufix);
_check_cache.emplace(i, result);
if (result)
return true;
}
return false;
}
template<typename IterableOfStrings>
bool check(
const IterableOfStrings& words,
const string& sentence
)
{
prepare_anagrams(words.begin(), words.end());
return _check(sentence);
}
int main() {
vector<string> words = {"a", "aa", "aaa", "aaaa", "aaaaa"};
string sentence = string(64'000, 'a') + string(1000, 'b');
cout << check(words, sentence) << endl;
string test = "даладнаєї 我下午4點開始有空。";
cout << test << endl;
for (size_t i=0; i < test.length(); ++i)
cout << i << " " << test[i];
cout << endl;
for (const auto& c : test)
cout << c;
cout << endl;
return 0;
}