prestige

Untitled

Feb 4th, 2013
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.20 KB | None | 0 0
  1. #include <string>
  2. #include <iostream>
  3. #include <map>
  4. #include <vector>
  5.  
  6. using std::cin;
  7. using std::cout;
  8. using std::string;
  9. using std::vector;
  10. using std::map;
  11. using std::pair;
  12. using std::make_pair;
  13. using std::max;
  14. // hash base. number that multiply previous hash coefficient to take the next value
  15. const long long khashbase = 31;
  16. int string_count;
  17. int max_string_size = 0;
  18. // string that contains the answer, the longest common substring
  19. string longest_common_substr = "";
  20. // container of all input strings
  21. vector<string> all_strings;
  22. // vector of the hash coefficients
  23. vector<long long> hash_coefficient;
  24. void reading_data () {
  25. cin >> string_count;
  26. all_strings.resize(string_count);
  27. for (size_t i = 0; i < string_count; i++) {
  28. cin >> all_strings[i];
  29. max_string_size = max (int(all_strings[i].length()), max_string_size);
  30. }
  31. }
  32.  
  33. void assign_hash_coefficients () {
  34. hash_coefficient.resize(max_string_size, 1);
  35. // assigning hash_coefficient by values
  36. for (size_t i = 1; i < max_string_size; i++) {
  37. hash_coefficient[i] = hash_coefficient[i - 1] * khashbase;
  38. }
  39. }
  40. // hashes string (third parameter) and stores to the substr_fr (second parameter)
  41. // substrings (with length equal to first parameter) hash values
  42. void find_string_hash (int & len, map<long long, pair<int, int> > & substr_frequency, string & str) {
  43. map<long long, pair<int, int> > unique_substr;
  44. int str_size = str.length();
  45. vector<long long> hashes (str_size, 0);
  46. for (int i = 0; i < str_size; i++) {
  47. hashes[i] = long long(str[i] - 'a' + 1) * hash_coefficient[i];
  48. if (i) {
  49. hashes[i] += hashes[i - 1];
  50. }
  51. }
  52. for (int i = 0; i + len - 1< str_size; i++) {
  53. long long substr_hash = hashes[i + len - 1];
  54. if (i) {
  55. substr_hash -= hashes[i - 1];
  56. }
  57. substr_hash = substr_hash * hash_coefficient[max_string_size - 1 - (len - 1) - i];
  58. unique_substr[substr_hash] = make_pair(0, i);
  59. }
  60. for (auto it = unique_substr.begin(); it != unique_substr.end(); it++) {
  61. substr_frequency[it->first].first++;
  62. substr_frequency[it->first].second = it->second.second;
  63. }
  64. }
  65. // looking for the common substring with length equal to parament len
  66. // true if she find otherwise false
  67. bool is_common_substring (int & len) {
  68. //carry frequency of the substrings hash values
  69. map<long long, pair<int, int> > substr_fr;
  70. for (size_t i = 0; i < string_count; i++) {
  71. find_string_hash(len, substr_fr, all_strings[i]);
  72. }
  73. for (auto it = substr_fr.begin(); it != substr_fr.end(); it++) {
  74. if (it->second.first == string_count) {
  75. longest_common_substr = all_strings[string_count - 1].substr(it->second.second, len);
  76. return true;
  77. }
  78. }
  79. return false;
  80. }
  81. // makes binary search by length of the longest common substring
  82. // we takes the number from the search and checking is any common substrings with such length
  83. void binary_search_length_common_substring() {
  84. int first = 0, last = max_string_size, mid = 0;
  85. while (first < last) {
  86. mid = first + (last - first) / 2;
  87. if (is_common_substring(mid)) {
  88. first = mid;
  89. } else {
  90. last = mid - 1;
  91. }
  92. }
  93. }
  94.  
  95. int main() {
  96. reading_data ();
  97. assign_hash_coefficients ();
  98. binary_search_length_common_substring ();
  99. cout << longest_common_substr;
  100. return 0;
  101. }
Advertisement
Add Comment
Please, Sign In to add comment