#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using std::begin;
using std::endl;
// Change to Boost's boyer_moore_horspool if you need a better complexity
template <typename HaystackIter, typename Needle, typename Output>
void search_all(HaystackIter first, HaystackIter last, Needle &needle,
Output out) {
for (HaystackIter it = first;
(it = std::search(it, last, begin(needle), end(needle))) != last;
it += needle.size())
*out++ = std::make_pair(it, &needle);
}
template <typename C, typename I, typename Value = typename C::value_type>
std::vector<Value> match_best(const C &dict, I from, I to) {
std::vector<std::pair<I, Value const *> > events;
for (auto &d : dict)
search_all(from, to, d, std::back_inserter(events));
std::sort(begin(events), end(events));
std::vector<std::pair<int, Value const *> > dp(to - from + 1, std::make_pair(std::numeric_limits<int>::min(), nullptr));
dp[0].first = 0;
for (auto &e : events) {
auto &old_res = dp[e.first - from + e.second->size()];
auto new_res = std::make_pair(dp[e.first - from].first + 1, e.second);
old_res = std::max(old_res, new_res);
}
std::vector<Value> result(std::max(0,dp.back().first));
int res_idx = result.size() - 1;
for (size_t i = dp.size() - 1; res_idx >= 0; i = i - dp[i].second->size())
result[res_idx--] = *dp[i].second;
return result;
}
std::vector<std::string> match_best(std::vector<std::string> const& dict,
std::string const& in)
{
return match_best(dict, begin(in), end(in));
}
int main() {
using namespace std;
std::vector<std::string> dict = {"this", "is", "a", "awe", "we", "awesome"};
std::string test = "thisisawesome";
vector<string> words = match_best(dict, test);
copy(begin(words), end(words), ostream_iterator<string>(cout, "\n"));
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8aXRlcmF0b3I+Cgp1c2luZyBzdGQ6OmJlZ2luOwp1c2luZyBzdGQ6OmVuZGw7CiAKLy8gQ2hhbmdlIHRvIEJvb3N0J3MgYm95ZXJfbW9vcmVfaG9yc3Bvb2wgaWYgeW91IG5lZWQgYSBiZXR0ZXIgY29tcGxleGl0eQp0ZW1wbGF0ZSA8dHlwZW5hbWUgSGF5c3RhY2tJdGVyLCB0eXBlbmFtZSBOZWVkbGUsIHR5cGVuYW1lIE91dHB1dD4Kdm9pZCBzZWFyY2hfYWxsKEhheXN0YWNrSXRlciBmaXJzdCwgSGF5c3RhY2tJdGVyIGxhc3QsIE5lZWRsZSAmbmVlZGxlLAogICAgICAgICAgICAgICAgT3V0cHV0IG91dCkgewogIGZvciAoSGF5c3RhY2tJdGVyIGl0ID0gZmlyc3Q7CiAgICAgICAoaXQgPSBzdGQ6OnNlYXJjaChpdCwgbGFzdCwgYmVnaW4obmVlZGxlKSwgZW5kKG5lZWRsZSkpKSAhPSBsYXN0OwogICAgICAgaXQgKz0gbmVlZGxlLnNpemUoKSkKICAgICpvdXQrKyA9IHN0ZDo6bWFrZV9wYWlyKGl0LCAmbmVlZGxlKTsKfQogCnRlbXBsYXRlIDx0eXBlbmFtZSBDLCB0eXBlbmFtZSBJLCB0eXBlbmFtZSBWYWx1ZSA9IHR5cGVuYW1lIEM6OnZhbHVlX3R5cGU+CnN0ZDo6dmVjdG9yPFZhbHVlPiBtYXRjaF9iZXN0KGNvbnN0IEMgJmRpY3QsIEkgZnJvbSwgSSB0bykgewogIHN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxJLCBWYWx1ZSBjb25zdCAqPiA+IGV2ZW50czsKICBmb3IgKGF1dG8gJmQgOiBkaWN0KQogICAgc2VhcmNoX2FsbChmcm9tLCB0bywgZCwgc3RkOjpiYWNrX2luc2VydGVyKGV2ZW50cykpOwogIHN0ZDo6c29ydChiZWdpbihldmVudHMpLCBlbmQoZXZlbnRzKSk7CiAgc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPGludCwgVmFsdWUgY29uc3QgKj4gPiBkcCh0byAtIGZyb20gKyAxLCBzdGQ6Om1ha2VfcGFpcihzdGQ6Om51bWVyaWNfbGltaXRzPGludD46Om1pbigpLCBudWxscHRyKSk7CiAgZHBbMF0uZmlyc3QgPSAwOwogIGZvciAoYXV0byAmZSA6IGV2ZW50cykgewogICAgYXV0byAmb2xkX3JlcyA9IGRwW2UuZmlyc3QgLSBmcm9tICsgZS5zZWNvbmQtPnNpemUoKV07CiAgICBhdXRvIG5ld19yZXMgPSBzdGQ6Om1ha2VfcGFpcihkcFtlLmZpcnN0IC0gZnJvbV0uZmlyc3QgKyAxLCBlLnNlY29uZCk7CiAgICBvbGRfcmVzID0gc3RkOjptYXgob2xkX3JlcywgbmV3X3Jlcyk7CiAgfQogIHN0ZDo6dmVjdG9yPFZhbHVlPiByZXN1bHQoc3RkOjptYXgoMCxkcC5iYWNrKCkuZmlyc3QpKTsKICBpbnQgcmVzX2lkeCA9IHJlc3VsdC5zaXplKCkgLSAxOwogIGZvciAoc2l6ZV90IGkgPSBkcC5zaXplKCkgLSAxOyByZXNfaWR4ID49IDA7IGkgPSBpIC0gZHBbaV0uc2Vjb25kLT5zaXplKCkpCiAgICByZXN1bHRbcmVzX2lkeC0tXSA9ICpkcFtpXS5zZWNvbmQ7CiAgcmV0dXJuIHJlc3VsdDsKfQoKc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IG1hdGNoX2Jlc3Qoc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IGNvbnN0JiBkaWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnN0cmluZyBjb25zdCYgaW4pCnsKICByZXR1cm4gbWF0Y2hfYmVzdChkaWN0LCBiZWdpbihpbiksIGVuZChpbikpOwp9CiAKaW50IG1haW4oKSB7CiAgdXNpbmcgbmFtZXNwYWNlIHN0ZDsKICBzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gZGljdCA9IHsidGhpcyIsICJpcyIsICJhIiwgImF3ZSIsICJ3ZSIsICJhd2Vzb21lIn07CiAgc3RkOjpzdHJpbmcgdGVzdCA9ICJ0aGlzaXNhd2Vzb21lIjsKICB2ZWN0b3I8c3RyaW5nPiB3b3JkcyA9IG1hdGNoX2Jlc3QoZGljdCwgdGVzdCk7CiAgY29weShiZWdpbih3b3JkcyksIGVuZCh3b3JkcyksIG9zdHJlYW1faXRlcmF0b3I8c3RyaW5nPihjb3V0LCAiXG4iKSk7Cn0K