Advertisement
Tvor0zhok

Алгоритм Рыбина-Карпа

May 30th, 2022
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.84 KB | None | 0 0
  1. using System;
  2.  
  3. namespace ConsoleApp1
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. Console.Write("Строка (текст): ");
  10. string t = Console.ReadLine();
  11.  
  12. Console.Write("Подстрока: ");
  13. string s = Console.ReadLine();
  14.  
  15. const long p = 37;
  16.  
  17. // =============================================================================
  18. // ШАГ 1: Подсчет значений степеней числа p: p^0, p^1, p^2, ..., p^{t.length}
  19. // =============================================================================
  20.  
  21. long[] degreeP = new long[t.Length]; degreeP[0] = 1;
  22.  
  23. for (int i = 1; i < t.Length; ++i)
  24. degreeP[i] = degreeP[i - 1] * p;
  25.  
  26. // =============================================================================
  27. // ШАГ 2: Подсчет хэш-значений для всех ПРЕФИКСОВ строки t
  28. // =============================================================================
  29.  
  30. long[] hashT = new long[t.Length]; hashT[0] = (t[0] - 'a' + 1);
  31.  
  32. for (int i = 1; i < t.Length; ++i)
  33. {
  34. hashT[i] = (t[i] - 'a' + 1) * degreeP[i];
  35. hashT[i] += hashT[i - 1];
  36. }
  37.  
  38. // =============================================================================
  39. // ШАГ 3: Подсчет хэш-значений для ПОДСТРОКИ s
  40. // =============================================================================
  41.  
  42. long hashS = 0;
  43.  
  44. for (int i = 0; i < s.Length; ++i)
  45. hashS += (s[i] - 'a' + 1) * degreeP[i];
  46.  
  47. // =============================================================================
  48. // ШАГ 4: Поиск подстроки за счет сравнения хэш-значений подстрок
  49. // =============================================================================
  50.  
  51. for (int i = 0; i + s.Length - 1 < t.Length; i++)
  52. {
  53. // Находим хэш-значение подстроки t[i..i + s.length - 1]
  54. long cur_hash = hashT[i + s.Length - 1];
  55.  
  56. if (i > 0) cur_hash -= hashT[i - 1];
  57.  
  58. // Приводим хэш-значения двух подстрок к одной степени
  59. if (cur_hash == hashS * degreeP[i]) // если хеш-значения равны, то и подстроки равны
  60. {
  61. Console.Write("{0} ", i); // выводим позицию i, с которой начинается повторение
  62. }
  63. }
  64. }
  65. }
  66. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement