Dada una string str , la tarea es encontrar la suma de las similitudes de str con cada uno de sus sufijos.
La similitud de las strings A y B es la longitud del prefijo más largo común a ambas strings, es decir, la similitud de «aabc» y «aab» es 3 y la de «qwer» y «abc» es 0 .
Ejemplos:
Entrada: str = “ababa”
Salida: 9
Los sufijos de str son “ababa”, “baba”, “aba”, “ba” y “a”. Las similitudes de estas strings con la string original “ababa” son 5, 0, 3, 0 y 1 respectivamente.
Por lo tanto, la respuesta es 5 + 0 + 3 + 0 + 1 = 9.
Entrada: str = “aaabaab”
Salida: 13
Enfoque: Calcule la array Z utilizando el algoritmo Z : para una string str[0..n-1], la array Z tiene la misma longitud que la string. Un elemento Z[i] de la array Z almacena la longitud de la substring más larga a partir de str[i], que también es un prefijo de str[0..n-1]. La primera entrada de la array Z es la longitud de la string.
Ahora, suma todos los elementos de la array Z para obtener la suma requerida de las similitudes.
A continuación se muestra la implementación del enfoque anterior:
C++
// C++ implementation of the approach #include <iostream> #include <string> #include <vector> using namespace std; // Function to calculate the Z-array for the given string void getZarr(string str, int n, int Z[]) { int L, R, k; // [L, R] make a window which matches with prefix of s L = R = 0; for (int i = 1; i < n; ++i) { // if i>R nothing matches so we will calculate. // Z[i] using naive way. if (i > R) { L = R = i; // R-L = 0 in starting, so it will start // checking from 0'th index. For example, // for "ababab" and i = 1, the value of R // remains 0 and Z[i] becomes 0. For string // "aaaaaa" and i = 1, Z[i] and R become 5 while (R < n && str[R - L] == str[R]) R++; Z[i] = R - L; R--; } else { // k = i-L so k corresponds to number which // matches in [L, R] interval. k = i - L; // if Z[k] is less than remaining interval // then Z[i] will be equal to Z[k]. // For example, str = "ababab", i = 3, R = 5 // and L = 2 if (Z[k] < R - i + 1) Z[i] = Z[k]; // For example str = "aaaaaa" and i = 2, R is 5, // L is 0 else { // else start from R and check manually L = i; while (R < n && str[R - L] == str[R]) R++; Z[i] = R - L; R--; } } } } // Function to return the similarity sum int sumSimilarities(string s, int n) { int Z[n] = { 0 }; // Compute the Z-array for the given string getZarr(s, n, Z); int total = n; // Summation of the Z-values for (int i = 1; i < n; i++) total += Z[i]; return total; } // Driver code int main() { string s = "ababa"; int n = s.length(); cout << sumSimilarities(s, n); return 0; }
Java
// Java implementation of the above approach public class GFG{ // Function to calculate the Z-array for the given string static void getZarr(String str, int n, int Z[]) { int L, R, k; // [L, R] make a window which matches with prefix of s L = R = 0; for (int i = 1; i < n; ++i) { // if i>R nothing matches so we will calculate. // Z[i] using naive way. if (i > R) { L = R = i; // R-L = 0 in starting, so it will start // checking from 0'th index. For example, // for "ababab" and i = 1, the value of R // remains 0 and Z[i] becomes 0. For string // "aaaaaa" and i = 1, Z[i] and R become 5 while (R < n && str.charAt(R - L) == str.charAt(R)) R++; Z[i] = R - L; R--; } else { // k = i-L so k corresponds to number which // matches in [L, R] interval. k = i - L; // if Z[k] is less than remaining interval // then Z[i] will be equal to Z[k]. // For example, str = "ababab", i = 3, R = 5 // and L = 2 if (Z[k] < R - i + 1) Z[i] = Z[k]; // For example str = "aaaaaa" and i = 2, R is 5, // L is 0 else { // else start from R and check manually L = i; while (R < n && str.charAt(R - L) == str.charAt(R)) R++; Z[i] = R - L; R--; } } } } // Function to return the similarity sum static int sumSimilarities(String s, int n) { int Z[] = new int[n] ; // Compute the Z-array for the given string getZarr(s, n, Z); int total = n; // Summation of the Z-values for (int i = 1; i < n; i++) total += Z[i]; return total; } // Driver code public static void main(String []args) { String s = "ababa"; int n = s.length(); System.out.println(sumSimilarities(s, n)); } // This code is contributed by Ryuga }
Python3
# Python3 implementation of the approach def getZarr(s, n, Z): L, R, k = 0, 0, 0 # [L, R] make a window which matches # with prefix of s for i in range(n): # if i>R nothing matches so we will # calculate Z[i] using naive way. if i > R: L, R = i, i ''' R-L = 0 in starting, so it will start checking from 0'th index. For example, for "ababab" and i = 1, the value of R remains 0 and Z[i] becomes 0. For string "aaaaaa" and i = 1, Z[i] and R become 5 ''' while R < n and s[R - L] == s[R]: R += 1 Z[i] = R - L R -= 1 else: # k = i-L so k corresponds to number # which matches in [L, R] interval. k = i - L # if Z[k] is less than remaining interval # then Z[i] will be equal to Z[k]. # For example, str = "ababab", i = 3, R = 5 # and L = 2 if Z[k] < R - i + 1: Z[i] = Z[k] else: L = i while R < n and s[R - L] == s[R]: R += 1 Z[i] = R - L R -= 1 def sumSimilarities(s, n): Z = [0 for i in range(n)] # Compute the Z-array for the # given string getZarr(s, n, Z) total = n # summation of the Z-values for i in range(n): total += Z[i] return total # Driver Code s = "ababa" n = len(s) print(sumSimilarities(s, n)) # This code is contributed # by Mohit kumar 29
C#
//C# implementation of the above approach using System; public class GFG{ // Function to calculate the Z-array for the given string static void getZarr(string str, int n, int []Z) { int L, R, k; // [L, R] make a window which matches with prefix of s L = R = 0; for (int i = 1; i < n; ++i) { // if i>R nothing matches so we will calculate. // Z[i] using naive way. if (i > R) { L = R = i; // R-L = 0 in starting, so it will start // checking from 0'th index. For example, // for "ababab" and i = 1, the value of R // remains 0 and Z[i] becomes 0. For string // "aaaaaa" and i = 1, Z[i] and R become 5 while (R < n && str[R - L] == str[R]) R++; Z[i] = R - L; R--; } else { // k = i-L so k corresponds to number which // matches in [L, R] interval. k = i - L; // if Z[k] is less than remaining interval // then Z[i] will be equal to Z[k]. // For example, str = "ababab", i = 3, R = 5 // and L = 2 if (Z[k] < R - i + 1) Z[i] = Z[k]; // For example str = "aaaaaa" and i = 2, R is 5, // L is 0 else { // else start from R and check manually L = i; while (R < n && str[R - L] == str[R]) R++; Z[i] = R - L; R--; } } } } // Function to return the similarity sum static int sumSimilarities(string s, int n) { int []Z = new int[n] ; // Compute the Z-array for the given string getZarr(s, n, Z); int total = n; // Summation of the Z-values for (int i = 1; i < n; i++) total += Z[i]; return total; } // Driver code static public void Main (){ string s = "ababa"; int n = s.Length; Console.WriteLine(sumSimilarities(s, n)); } // This code is contributed by ajit. }
Javascript
<script> // Javascript implementation of // the above approach // Function to calculate the Z-array // for the given string function getZarr(str, n, Z) { let L, R, k; // [L, R] make a window which matches // with prefix of s L = R = 0; for (let i = 1; i < n; ++i) { // if i>R nothing matches so // we will calculate. // Z[i] using naive way. if (i > R) { L = R = i; // R-L = 0 in starting, so it will start // checking from 0'th index. For example, // for "ababab" and i = 1, the value of R // remains 0 and Z[i] becomes 0. For string // "aaaaaa" and i = 1, Z[i] and R become 5 while (R < n && str[R - L] == str[R]) R++; Z[i] = R - L; R--; } else { // k = i-L so k corresponds // to number which // matches in [L, R] interval. k = i - L; // if Z[k] is less than // remaining interval // then Z[i] will be equal to Z[k]. // For example, str = "ababab", // i = 3, R = 5 // and L = 2 if (Z[k] < R - i + 1) Z[i] = Z[k]; // For example str = "aaaaaa" // and i = 2, R is 5, // L is 0 else { // else start from R and // check manually L = i; while (R < n && str[R - L] == str[R]) R++; Z[i] = R - L; R--; } } } } // Function to return the similarity sum function sumSimilarities(s, n) { let Z = new Array(n); Z.fill(0); // Compute the Z-array for the given string getZarr(s, n, Z); let total = n; // Summation of the Z-values for (let i = 1; i < n; i++) total += Z[i]; return total; } let s = "ababa"; let n = s.length; document.write(sumSimilarities(s, n)); </script>
9
Complejidad de Tiempo: ON)
Espacio Auxiliar: O(N)
Publicación traducida automáticamente
Artículo escrito por shaleenahuja28 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA