#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <sstream>
#include <algorithm>
using namespace std;
vector<int> str2vec (const string& s) {
string s1{s};
replace_if (s1.begin(), s1.end(), [](char c) { return c == ';'; }, ' ');
vector<int> v;
stringstream ss(s1);
copy (istream_iterator<int>(ss), istream_iterator<int>(), back_inserter(v));
return v;
}
typedef vector<int>::const_iterator iter;
iter approximate_find (const vector<int>& needle, const vector<int>& input, double prec=0) {
iter i=input.cbegin();
while (i < input.cend()-needle.size()) {
bool found = true;
for (iter j=needle.cbegin(); j != needle.cend(); ++j, ++i)
if (fabs (*i-*j) > *i*prec) {
found = false;
++i;
break;
}
if (found)
return i-needle.size();
}
return input.cend();
}
int main() {
string input { "100;1000;10000;100000;900;75;871;347;" };
vector<string> dictionary {
"77;15;224;34;781;574;1561;"
,"800;8000;80000;850;"
,"13;16;61;516;4;864;61;98;46;8189;63;"
};
vector<vector<int>> v_dic;
transform (dictionary.begin(), dictionary.end(), back_inserter(v_dic), str2vec);
vector<int> v_input = str2vec(input);
for_each (v_dic.begin(), v_dic.end(), [&](const vector<int>& needle) {
iter i = approximate_find (needle, v_input, 0.2);
if (i != v_input.cend()) {
copy (i, i+needle.size(), ostream_iterator<int>(cout, ";"));
cout << " matches ";
}
else {
cout << "not found: ";
}
copy (needle.begin(), needle.end(), ostream_iterator<int>(cout, ";"));
cout << endl;
});
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxzc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdmVjdG9yPGludD4gc3RyMnZlYyAoY29uc3Qgc3RyaW5nJiBzKSB7CglzdHJpbmcgczF7c307CglyZXBsYWNlX2lmIChzMS5iZWdpbigpLCBzMS5lbmQoKSwgW10oY2hhciBjKSB7IHJldHVybiBjID09ICc7JzsgfSwgJyAnKTsKCXZlY3RvcjxpbnQ+IHY7CglzdHJpbmdzdHJlYW0gc3MoczEpOwoJY29weSAoaXN0cmVhbV9pdGVyYXRvcjxpbnQ+KHNzKSwgaXN0cmVhbV9pdGVyYXRvcjxpbnQ+KCksIGJhY2tfaW5zZXJ0ZXIodikpOwoJCglyZXR1cm4gdjsKfQoKdHlwZWRlZiB2ZWN0b3I8aW50Pjo6Y29uc3RfaXRlcmF0b3IgaXRlcjsKCml0ZXIgYXBwcm94aW1hdGVfZmluZCAoY29uc3QgdmVjdG9yPGludD4mIG5lZWRsZSwgY29uc3QgdmVjdG9yPGludD4mIGlucHV0LCBkb3VibGUgcHJlYz0wKSB7CglpdGVyIGk9aW5wdXQuY2JlZ2luKCk7Cgl3aGlsZSAoaSA8IGlucHV0LmNlbmQoKS1uZWVkbGUuc2l6ZSgpKSB7CgkJYm9vbCBmb3VuZCA9IHRydWU7CgkJZm9yIChpdGVyIGo9bmVlZGxlLmNiZWdpbigpOyBqICE9IG5lZWRsZS5jZW5kKCk7ICsraiwgKytpKQoJCSAgIGlmIChmYWJzICgqaS0qaikgPiAqaSpwcmVjKSB7CgkJICAgCSAgZm91bmQgPSBmYWxzZTsKCQkgICAJICArK2k7CgkJICAgICAgYnJlYWs7CgkJICAgfQoJCWlmIChmb3VuZCkKCQkgICByZXR1cm4gaS1uZWVkbGUuc2l6ZSgpOwoJfQoJcmV0dXJuIGlucHV0LmNlbmQoKTsKfQoKaW50IG1haW4oKSB7CglzdHJpbmcgaW5wdXQgeyAiMTAwOzEwMDA7MTAwMDA7MTAwMDAwOzkwMDs3NTs4NzE7MzQ3OyIgfTsKCXZlY3RvcjxzdHJpbmc+IGRpY3Rpb25hcnkgewoJCSAiNzc7MTU7MjI0OzM0Ozc4MTs1NzQ7MTU2MTsiCgkJLCI4MDA7ODAwMDs4MDAwMDs4NTA7IgoJCSwiMTM7MTY7NjE7NTE2OzQ7ODY0OzYxOzk4OzQ2OzgxODk7NjM7IgoJfTsKCQoJdmVjdG9yPHZlY3RvcjxpbnQ+PiB2X2RpYzsKCXRyYW5zZm9ybSAoZGljdGlvbmFyeS5iZWdpbigpLCBkaWN0aW9uYXJ5LmVuZCgpLCBiYWNrX2luc2VydGVyKHZfZGljKSwgc3RyMnZlYyk7CiAgICB2ZWN0b3I8aW50PiB2X2lucHV0ID0gc3RyMnZlYyhpbnB1dCk7CiAgICAKICAgIGZvcl9lYWNoICh2X2RpYy5iZWdpbigpLCB2X2RpYy5lbmQoKSwgWyZdKGNvbnN0IHZlY3RvcjxpbnQ+JiBuZWVkbGUpIHsKICAgIAlpdGVyIGkgPSBhcHByb3hpbWF0ZV9maW5kIChuZWVkbGUsIHZfaW5wdXQsIDAuMik7CiAgICAJaWYgKGkgIT0gdl9pbnB1dC5jZW5kKCkpIHsKICAgIAkgIGNvcHkgKGksIGkrbmVlZGxlLnNpemUoKSwgb3N0cmVhbV9pdGVyYXRvcjxpbnQ+KGNvdXQsICI7IikpOwogICAJCSAgY291dCA8PCAiIG1hdGNoZXMgIjsKICAgIAl9CiAgICAJZWxzZSB7CiAgICAJCWNvdXQgPDwgIm5vdCBmb3VuZDogIjsKICAgIAl9CiAgIAkgICAgY29weSAobmVlZGxlLmJlZ2luKCksIG5lZWRsZS5lbmQoKSwgb3N0cmVhbV9pdGVyYXRvcjxpbnQ+KGNvdXQsICI7IikpOwogCSAgICBjb3V0IDw8IGVuZGw7CiAgICB9KTsKfQo=