Advertisement
Infiniti_Inter

4ok164

Nov 17th, 2019
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.01 KB | None | 0 0
  1. using System;
  2. using System.Text;
  3. using System.IO;
  4. namespace Hash
  5. {
  6. class Program
  7. {
  8. //Метод для получения хеш-значения для подстроки с индексами L и R
  9. static long GetHash(long[] h, int L, int R)
  10. {
  11. if (L > 0) return h[R] - h[L - 1];
  12. return h[R];
  13. }
  14. //Метод для получения хеш-значения для «перевернутой» подстроки с индексами L и R
  15. static long GetHashRevers(long[] h_r, int L, int R)
  16. {
  17. if (R < h_r.Length - 1) return h_r[L] - h_r[R + 1];
  18. return h_r[L];
  19. }
  20. //Метод возвращает true, если строка палиндром, иначе false
  21. static bool IsPalindrome(long[] h, long[] h_r, long[] pwp, int L, int R)
  22. {
  23. return GetHash(h, L, R) * pwp[h.Length - R - 1] == GetHashRevers(h_r, L, R) * pwp[L];
  24. }
  25. //Метод для вывода на экран всех палиндром строки S
  26. static void Print(int[] oddCount, int[] evenCount, string s)
  27. {
  28. Console.WriteLine("Палиндромы:");
  29. for (int i = 0; i < oddCount.Length; ++i) //вывод палиндромов нечетной длины
  30. {
  31. if (oddCount[i] > 1) //1
  32. Console.WriteLine(s.Substring(i - oddCount[i] + 1, oddCount[i] * 2 - 1));
  33. }
  34. for (int i = 0; i < evenCount.Length; ++i) //вывод палиндромов четной длины
  35. {
  36. if (evenCount[i] > 0)
  37. Console.WriteLine(s.Substring(i - evenCount[i], evenCount[i] * 2));
  38. }
  39. }
  40. //length - длинна сгенерированной строки
  41. static string generator(int length)
  42. {
  43. Random rnd = new Random();
  44. StringBuilder result = new StringBuilder();
  45. for (int i = 0; i < length; ++i)
  46. {
  47. char c = (char)('a' + rnd.Next(0, 26));
  48. result.Append(c);
  49. }
  50. return result.ToString();
  51. }
  52. static void Main(string[] args) //основной метод
  53. {
  54. Console.Write("S= ");
  55.  
  56.  
  57. string s = generator(10000);
  58.  
  59. using (StreamWriter output = new StreamWriter("D:/output.txt", false))
  60. {
  61. output.WriteLine(s);
  62. Console.WriteLine(s);
  63. }
  64. int n = s.Length; //2
  65. const long P = 37;
  66. //вычисляем массив степеней
  67. long[] pwp = new long[n];
  68. pwp[0] = 1;
  69. for (int i = 1; i < n; i++)
  70. {
  71. pwp[i] = pwp[i - 1] * P;
  72.  
  73. }
  74. //вычисляем массив хэш-значений для всех префиксов строки S и
  75. //перевернутой строки
  76. long[] h = new long[n];
  77. long[] h_r = new long[n];
  78. for (int i = 0; i < n; i++)
  79. {
  80. h[i] = (s[i] - 'a' + 1) * pwp[i];
  81. h_r[n - 1 - i] = (s[n - 1 - i] - 'a' + 1) * pwp[i];
  82. if (i > 0)
  83. {
  84. h[i] += h[i - 1];
  85. h_r[n - 1 - i] += h_r[n - i];
  86. }
  87. }
  88. //поиск палиндромов нечетной длины
  89. int[] oddCount = new int[n];
  90. for (int i = 0; i < n; i++)
  91. {
  92. int left = 1, right = Math.Min(i + 1, n - i);
  93. while (left <= right)
  94. {
  95. int middle = (left + right) / 2;
  96. if (IsPalindrome(h, h_r, pwp, i - middle + 1, i + middle - 1))
  97. {
  98. oddCount[i] = middle;
  99. left = middle + 1;
  100. }
  101. else
  102. {
  103. right = middle - 1;
  104. }
  105. }
  106. }
  107. //поиск палиндромов четной длины
  108. int[] evenCount = new int[n];
  109. for (int i = 0; i < n; i++)
  110. {
  111. int left = 1, right = Math.Min(i, n - i);
  112. while (left <= right)
  113. {
  114. int middle = (left + right) / 2;
  115. if (IsPalindrome(h, h_r, pwp, i - middle, i + middle - 1))
  116. {
  117. evenCount[i] = middle;
  118. left = middle + 1;
  119. }
  120. else
  121. {
  122. right = middle - 1;
  123. }
  124. }
  125. }
  126. Print(oddCount, evenCount, s); //вывод на экран всех палиндромов
  127. }
  128. }
  129. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement