Suma de similitudes de string con todos sus sufijos

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:
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>
Producción: 

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *