Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <iostream>
- #include <map>
- #include <vector>
- using std::cin;
- using std::cout;
- using std::string;
- using std::vector;
- using std::map;
- using std::pair;
- using std::make_pair;
- using std::max;
- // hash base. number that multiply previous hash coefficient to take the next value
- const long long khashbase = 31;
- int string_count;
- int max_string_size = 0;
- // string that contains the answer, the longest common substring
- string longest_common_substr = "";
- // container of all input strings
- vector<string> all_strings;
- // vector of the hash coefficients
- vector<long long> hash_coefficient;
- void reading_data () {
- cin >> string_count;
- all_strings.resize(string_count);
- for (size_t i = 0; i < string_count; i++) {
- cin >> all_strings[i];
- max_string_size = max (int(all_strings[i].length()), max_string_size);
- }
- }
- void assign_hash_coefficients () {
- hash_coefficient.resize(max_string_size, 1);
- // assigning hash_coefficient by values
- for (size_t i = 1; i < max_string_size; i++) {
- hash_coefficient[i] = hash_coefficient[i - 1] * khashbase;
- }
- }
- // hashes string (third parameter) and stores to the substr_fr (second parameter)
- // substrings (with length equal to first parameter) hash values
- void find_string_hash (int & len, map<long long, pair<int, int> > & substr_frequency, string & str) {
- map<long long, pair<int, int> > unique_substr;
- int str_size = str.length();
- vector<long long> hashes (str_size, 0);
- for (int i = 0; i < str_size; i++) {
- hashes[i] = long long(str[i] - 'a' + 1) * hash_coefficient[i];
- if (i) {
- hashes[i] += hashes[i - 1];
- }
- }
- for (int i = 0; i + len - 1< str_size; i++) {
- long long substr_hash = hashes[i + len - 1];
- if (i) {
- substr_hash -= hashes[i - 1];
- }
- substr_hash = substr_hash * hash_coefficient[max_string_size - 1 - (len - 1) - i];
- unique_substr[substr_hash] = make_pair(0, i);
- }
- for (auto it = unique_substr.begin(); it != unique_substr.end(); it++) {
- substr_frequency[it->first].first++;
- substr_frequency[it->first].second = it->second.second;
- }
- }
- // looking for the common substring with length equal to parament len
- // true if she find otherwise false
- bool is_common_substring (int & len) {
- //carry frequency of the substrings hash values
- map<long long, pair<int, int> > substr_fr;
- for (size_t i = 0; i < string_count; i++) {
- find_string_hash(len, substr_fr, all_strings[i]);
- }
- for (auto it = substr_fr.begin(); it != substr_fr.end(); it++) {
- if (it->second.first == string_count) {
- longest_common_substr = all_strings[string_count - 1].substr(it->second.second, len);
- return true;
- }
- }
- return false;
- }
- // makes binary search by length of the longest common substring
- // we takes the number from the search and checking is any common substrings with such length
- void binary_search_length_common_substring() {
- int first = 0, last = max_string_size, mid = 0;
- while (first < last) {
- mid = first + (last - first) / 2;
- if (is_common_substring(mid)) {
- first = mid;
- } else {
- last = mid - 1;
- }
- }
- }
- int main() {
- reading_data ();
- assign_hash_coefficients ();
- binary_search_length_common_substring ();
- cout << longest_common_substr;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment