I did a substring search in a string using a variation of the Boyer-Moore algorithm. I have a search for a bad character with gain, i.e. I store all the positions in the parser for each character. I do this for the subsequent shift in comparison. I also have a search for a good suffix through the Z-function and then calculate the positions where the repeated substring ends in my string. And in the end, I just find the maximum step by comparing the obtained 2 values and 1 (for safety). But my cat doesn’t work somewhere, but I can’t figure out where, please tell me.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using ll = long long;
using std::cin;
using std::cout;
struct words
{
std::string s = "";
ll word_pos;
ll line;
};
std::vector<ll> z_func(const std::string& s)
{
ll n = s.size();
std::vector<ll> z(n);
z[0] = 0;
ll l = 0, r = 0;
for (int i = 1; i < n; i++)
{
if (i < r)
z[i] = std::min(z[i - l], r - i);
while (i + z[i] < n and s[z[i]] == s[i + z[i]])
{
z[i]++;
}
if (i + z[i] > r)
{
l = i;
r = i + z[i];
}
}
return z;
}
ll max(ll x, ll y, ll z)
{
return std::max(std::max(x, y), z);
}
int main()
{
cin.tie(NULL);
cout.tie(NULL);
std::ios_base::sync_with_stdio(false);
std::string alp = "abcdefghijklmnopqrstuvwxyz";
std::vector<words> m;
char c;
std::string wor = "", word;
ll word_poss = 0, line_level = 0;
words temp;
std::string pat = "";
wor = "";
while ((c = getchar()) != 'n')
{
if (c != ' ')
{
c = tolower(c);
wor += c;
}
}
word = "";
while ((c = getchar()) != EOF and c != '#')
{
if (c == 'n')
{
pat = word;
break;
}
else
{
if (c != ' ')
{
c = tolower(c);
word += c;
}
}
}
pat = word;
std::vector<std::vector<int>> PPS(26);
for (int i = 0; i < pat.size(); i++)
{
ll pos = alp.find(pat[i]);
PPS[pos].push_back(i);
}
for (int i = 0; i < 26; i++)
{
PPS[i].push_back(1e9);
}
std::string rev_pat = pat;
reverse(rev_pat.begin(), rev_pat.end());
std::vector<ll> Nj = z_func(rev_pat);
reverse(Nj.begin(), Nj.end());
std::vector<ll> Li(pat.size(), 0);
for (int i = 0; i < pat.size(); i++)
{
if (Nj[i] != 0)
{
Li[pat.size() - Nj[i]] = i - Nj[i] + 1;
}
}
ll i = pat.size() - 1, nach = pat.size() - 1, kol = 0, start;
bool f = true, fl = true;
while (nach < ll(wor.size()))
{
i = nach;
start = i;
for (int j = pat.size() - 1; j >= 0; j--)
{
if (pat[j] != wor[i])
{
ll pos = alp.find(wor[i]);
ll zn = 1e9, zn2;
for (int t = 0; t < PPS[pos].size(); t++)
{
if (abs(j - PPS[pos][t]) < zn)
{
zn = abs(j - PPS[pos][t]);
}
}
//auto it = std::upper_bound(PPS[pos].begin(), PPS[pos].end(), pat.size() - j - 1);
//zn = *it;
if (zn >= 1e8)
{
zn = j;
}
if (nach == i)
{
zn2 = 0;
}
else
{
zn2 = Li[j];
}
nach += max(zn, zn2, 1LL);
f = false;
break;
}
i--;
}
if (f)
{
cout << start - pat.size() + 1 << 'n';
nach = start + 1;
fl = false;
}
else
{
f = true;
}
}
return 0;
}
2