#include <string>
#include <iostream>
#include <fstream>
#include <climits>
#include <array>
#include <vector>
using iter_type = std::string::const_iterator;
iter_type find_pattern_in(iter_type txt_beg, iter_type txt_end,
iter_type pat_beg, iter_type pat_end)
{
const unsigned txt_len = txt_end - txt_beg;
const unsigned pat_len = pat_end - pat_beg;
// boyer-moore-horspool
if (txt_len >= pat_len)
{
std::array<int, UCHAR_MAX> shift;
shift.fill(-1);
for (unsigned i = 0; i < pat_len - 1; ++i)
shift[static_cast<unsigned char>(pat_beg[i])] = i;
unsigned i = 0;
unsigned m = pat_len;
while (i <= txt_len - pat_len)
{
int j = pat_len - 1;
while (j >= 0 && pat_beg[j] == txt_beg[i + j])
--j;
if (j < 0)
return txt_beg + i;
i += pat_len - 1;
i -= shift[static_cast<unsigned char>(txt_beg[i])];
}
}
return txt_end;
}
iter_type find_pattern(const std::string& text, std::string pattern)
{
// * in the pattern indicates a match of 0 to any number of characters.
// \* indicates a literal match for the asterisk.
std::vector<std::string> pats; // list of literal patterns which must occur in
// text, consecutively and with no overlap
{
unsigned last_pos = 0;
unsigned pos = 0;
while ((pos = pattern.find('*', pos)) != std::string::npos)
{
if (pos == 0 || pattern[pos - 1] == '\\')
pattern.erase(pos ? pos - 1 : pos, 1);
else
{
pats.emplace_back(pattern.substr(last_pos, pos - last_pos));
last_pos = ++pos;
}
}
if (last_pos < pattern.length())
pats.emplace_back(pattern.substr(last_pos));
}
iter_type last_loc = text.end();
iter_type loc = text.begin();
for (auto& pat : pats)
{
last_loc = loc = find_pattern_in(loc, text.end(), pat.begin(), pat.end());
if (loc == text.end())
return text.end();
loc += pat.length();
}
return last_loc;
}
#include <sstream>
std::istringstream in( // text,pattern
R"(Hello,ell
This is good, is
Mothra,M*ra
Old,Young
bY T,Y T
lnHLp5kGMHeYsoA7NXFrL8Ij Su,S
f3SFw5trxxZIaKec,wa3fZceFxS
)"
);
int main(int argc, char* argv[])
{
// std::ifstream in(argv[1]);
std::string text, pattern;
while (std::getline(in, text, ',') && std::getline(in, pattern))
std::cout << (text.end() != find_pattern(text, pattern) ? "true\n" : "false\n");
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnN0cmVhbT4KI2luY2x1ZGUgPGNsaW1pdHM+CiNpbmNsdWRlIDxhcnJheT4KI2luY2x1ZGUgPHZlY3Rvcj4KCnVzaW5nIGl0ZXJfdHlwZSA9IHN0ZDo6c3RyaW5nOjpjb25zdF9pdGVyYXRvcjsKCml0ZXJfdHlwZSBmaW5kX3BhdHRlcm5faW4oaXRlcl90eXBlIHR4dF9iZWcsIGl0ZXJfdHlwZSB0eHRfZW5kLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyX3R5cGUgcGF0X2JlZywgaXRlcl90eXBlIHBhdF9lbmQpCnsKICAgIGNvbnN0IHVuc2lnbmVkIHR4dF9sZW4gPSB0eHRfZW5kIC0gdHh0X2JlZzsKICAgIGNvbnN0IHVuc2lnbmVkIHBhdF9sZW4gPSBwYXRfZW5kIC0gcGF0X2JlZzsKCiAgICAvLyBib3llci1tb29yZS1ob3JzcG9vbAogICAgaWYgKHR4dF9sZW4gPj0gcGF0X2xlbikKICAgIHsKICAgICAgICBzdGQ6OmFycmF5PGludCwgVUNIQVJfTUFYPiAgc2hpZnQ7CiAgICAgICAgc2hpZnQuZmlsbCgtMSk7CgogICAgICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBwYXRfbGVuIC0gMTsgKytpKQogICAgICAgICAgICBzaGlmdFtzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPihwYXRfYmVnW2ldKV0gPSBpOwoKICAgICAgICB1bnNpZ25lZCBpID0gMDsKICAgICAgICB1bnNpZ25lZCBtID0gcGF0X2xlbjsKCiAgICAgICAgd2hpbGUgKGkgPD0gdHh0X2xlbiAtIHBhdF9sZW4pCiAgICAgICAgewogICAgICAgICAgICBpbnQgaiA9IHBhdF9sZW4gLSAxOwoKICAgICAgICAgICAgd2hpbGUgKGogPj0gMCAmJiBwYXRfYmVnW2pdID09IHR4dF9iZWdbaSArIGpdKQogICAgICAgICAgICAgICAgLS1qOwoKICAgICAgICAgICAgaWYgKGogPCAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHR4dF9iZWcgKyBpOwoKICAgICAgICAgICAgaSArPSBwYXRfbGVuIC0gMTsKICAgICAgICAgICAgaSAtPSBzaGlmdFtzdGF0aWNfY2FzdDx1bnNpZ25lZCBjaGFyPih0eHRfYmVnW2ldKV07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiB0eHRfZW5kOwp9CgppdGVyX3R5cGUgZmluZF9wYXR0ZXJuKGNvbnN0IHN0ZDo6c3RyaW5nJiB0ZXh0LCBzdGQ6OnN0cmluZyBwYXR0ZXJuKQp7CiAgICAvLyAqIGluIHRoZSBwYXR0ZXJuIGluZGljYXRlcyBhIG1hdGNoIG9mIDAgdG8gYW55IG51bWJlciBvZiBjaGFyYWN0ZXJzLgogICAgLy8gXCogaW5kaWNhdGVzIGEgbGl0ZXJhbCBtYXRjaCBmb3IgdGhlIGFzdGVyaXNrLgoKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBwYXRzOyAgLy8gbGlzdCBvZiBsaXRlcmFsIHBhdHRlcm5zIHdoaWNoIG11c3Qgb2NjdXIgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGV4dCwgY29uc2VjdXRpdmVseSBhbmQgd2l0aCBubyBvdmVybGFwCgogICAgewogICAgICAgIHVuc2lnbmVkIGxhc3RfcG9zID0gMDsKICAgICAgICB1bnNpZ25lZCBwb3MgPSAwOwogICAgICAgIHdoaWxlICgocG9zID0gcGF0dGVybi5maW5kKCcqJywgcG9zKSkgIT0gc3RkOjpzdHJpbmc6Om5wb3MpCiAgICAgICAgewogICAgICAgICAgICBpZiAocG9zID09IDAgfHwgcGF0dGVybltwb3MgLSAxXSA9PSAnXFwnKQogICAgICAgICAgICAgICAgcGF0dGVybi5lcmFzZShwb3MgPyBwb3MgLSAxIDogcG9zLCAxKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwYXRzLmVtcGxhY2VfYmFjayhwYXR0ZXJuLnN1YnN0cihsYXN0X3BvcywgcG9zIC0gbGFzdF9wb3MpKTsKICAgICAgICAgICAgICAgIGxhc3RfcG9zID0gKytwb3M7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChsYXN0X3BvcyA8IHBhdHRlcm4ubGVuZ3RoKCkpCiAgICAgICAgICAgIHBhdHMuZW1wbGFjZV9iYWNrKHBhdHRlcm4uc3Vic3RyKGxhc3RfcG9zKSk7CiAgICB9CgogICAgaXRlcl90eXBlIGxhc3RfbG9jID0gdGV4dC5lbmQoKTsKICAgIGl0ZXJfdHlwZSBsb2MgPSB0ZXh0LmJlZ2luKCk7CiAgICBmb3IgKGF1dG8mIHBhdCA6IHBhdHMpCiAgICB7CiAgICAgICAgbGFzdF9sb2MgPSBsb2MgPSBmaW5kX3BhdHRlcm5faW4obG9jLCB0ZXh0LmVuZCgpLCBwYXQuYmVnaW4oKSwgcGF0LmVuZCgpKTsKICAgICAgICBpZiAobG9jID09IHRleHQuZW5kKCkpCiAgICAgICAgICAgIHJldHVybiB0ZXh0LmVuZCgpOwoKICAgICAgICBsb2MgKz0gcGF0Lmxlbmd0aCgpOwogICAgfQoKICAgIHJldHVybiBsYXN0X2xvYzsKfQoKI2luY2x1ZGUgPHNzdHJlYW0+CnN0ZDo6aXN0cmluZ3N0cmVhbSBpbiggIC8vIHRleHQscGF0dGVybgpSIihIZWxsbyxlbGwKVGhpcyBpcyBnb29kLCBpcwpNb3RocmEsTSpyYQpPbGQsWW91bmcKYlkgVCxZIFQKbG5ITHA1a0dNSGVZc29BN05YRnJMOElqIFN1LFMKZjNTRnc1dHJ4eFpJYUtlYyx3YTNmWmNlRnhTCikiCik7CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKQp7CiAgICAvLyBzdGQ6Omlmc3RyZWFtIGluKGFyZ3ZbMV0pOwoKICAgIHN0ZDo6c3RyaW5nIHRleHQsIHBhdHRlcm47CgogICAgd2hpbGUgKHN0ZDo6Z2V0bGluZShpbiwgdGV4dCwgJywnKSAmJiBzdGQ6OmdldGxpbmUoaW4sIHBhdHRlcm4pKQogICAgICAgIHN0ZDo6Y291dCA8PCAodGV4dC5lbmQoKSAhPSBmaW5kX3BhdHRlcm4odGV4dCwgcGF0dGVybikgPyAidHJ1ZVxuIiA6ICJmYWxzZVxuIik7Cn0=