Infiniti_Inter

Практика 12 № 11

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