#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// Function to compute the Z-array
vector<int> z_algorithm(const string &s) {
int n = s.size();
vector<int> z(n);
int l = 0, r = 0;
for (int i = 1; i < n; ++i) {
if (i > r) {
l = r = i;
while (r < n && s[r] == s[r - l]) {
r++;
}
z[i] = r - l;
r--;
} else {
int k = i - l;
if (z[k] < r - i + 1) {
z[i] = z[k];
} else {
l = i;
while (r < n && s[r] == s[r - l]) {
r++;
}
z[i] = r - l;
r--;
}
}
}
return z;
}
// Function to find the best starting index of the substring in text
int find_best_substring(const string &text, const string &pattern) {
int n = text.size(), m = pattern.size();
// Z-algorithm on pattern + "$" + text
string concat1 = pattern + "$" + text;
vector<int> z1 = z_algorithm(concat1);
// Z-algorithm on reversed pattern + "$" + reversed text
string reversed_pattern = string(pattern.rbegin(), pattern.rend());
string reversed_text = string(text.rbegin(), text.rend());
string concat2 = reversed_pattern + "$" + reversed_text;
vector<int> z2 = z_algorithm(concat2);
int max_length = -1;
int best_index = -1;
// Find maximum overlap
for (int i = m + 1; i < z1.size(); ++i) {
int prefix_length = z1[i];
int suffix_length = (i - (m + 1) < z2.size()) ? z2[z2.size() - (i - (m + 1))] : 0;
if (prefix_length + suffix_length >= m) {
int start_index = i - (m + 1);
if (prefix_length + suffix_length > max_length) {
max_length = prefix_length + suffix_length;
best_index = start_index;
}
}
}
return best_index;
}
int main() {
string text = "abcdefg";
string pattern = "bcdffg";
int result = find_best_substring(text, pattern);
cout << "Best starting index: " << result << endl;
return 0;
}