Imprima todas las formas posibles de convertir una string en otra string | Editar-Distancia

Prerrequisito: Programación Dinámica | Conjunto 5 (Editar distancia) 
Dadas dos strings str1 y str2, la tarea es imprimir todas las formas posibles de convertir ‘str1’ en ‘str2’. 
A continuación se muestran las operaciones que se pueden realizar en «str1»: 
 

  1. Insertar
  2. Remover
  3. Reemplazar

Todas las operaciones anteriores son de igual costo. La tarea es imprimir todas las diversas formas de convertir ‘str1’ en ‘str2’ usando el número mínimo de ediciones (operaciones) requeridas, donde una «forma» se compone de la serie de todas las operaciones requeridas. 
Ejemplos: 
 

Entrada: str1 = “abcdef”, str2 = “axcdfdh” 
Salida:  
Método 1: 
Agregar h 
Cambiar f por d 
Cambiar e por f 
Cambiar b por x
Método 2: 
Cambiar f por h 
Agregar d 
Cambiar e por f 
Cambiar b por x
Método 3: 
Cambie f por h 
Cambie e por d 
Agregue f 
Cambie b por x 
 

Enfoque para imprimir una forma posible:

El enfoque para encontrar el número mínimo de ediciones se ha discutido en esta publicación . Para imprimir de una forma posible, itere desde la esquina inferior derecha de la array DP formada con el método Distancia mínima de edición . Compruebe si el carácter perteneciente a ese elemento en ambas strings es igual o no. Si es así, significa que no necesita edición y DP[i][j] se copió de DP[i-1][j-1]. 
 

If str1[i-1] == str2[j-1], proceed diagonally. 

Tenga en cuenta que dado que la array DP contiene una fila y una columna adicionales en los índices 0, los índices de string se reducirán en uno. es decir, DP[i][j] corresponde al índice i-1 de str1 y al índice j-1 de str2.
Ahora bien, si los caracteres no fueran iguales, eso significa que este elemento de la array DP[i][j] se obtuvo del mínimo de DP[i-1][j-1], DP[i][j-1] y DP [i-1][j], más 1. Por lo tanto, verifique de dónde proviene este elemento. 
 

1. If DP[i][j] == DP[i-1][j-1] + 1 
        It means the character was replaced from str1[i] to str2[j]. Proceed diagonally.
2. If DP[i][j] == DP[i][j-1] + 1
        It means the character was Added from str2[j]. Proceed left.
3. If DP[i][j] == DP[i-1][j] + 1
        It means the character str1[i] was deleted. Proceed up.

Una vez que se alcanza el final, es decir, (i==0 o j==0) de cualquiera de las strings, se realiza la conversión de una string a otra. Habremos impreso todo el conjunto de operaciones necesarias. 
A continuación se muestra la implementación del enfoque anterior: 
 

C++

// C++ program to print one possible
// way of converting a string to another
#include <bits/stdc++.h>
using namespace std;
 
int DP[100][100];
 
// Function to print the steps
void printChanges(string s1, string s2,
                         int dp[][100])
{
    int i = s1.length();
    int j = s2.length();
 
    // check till the end
    while (i and j)
    {
        // if characters are same
        if (s1[i - 1] == s2[j - 1])
        {
            i--;
            j--;
        }
 
        // Replace
        else if (dp[i][j] == dp[i - 1][j - 1] + 1)
        {
            cout << "change " << s1[i - 1]
                 << " to " << s2[j - 1] << endl;
            i--;
            j--;
        }
 
        // Delete the character
        else if (dp[i][j] == dp[i - 1][j] + 1)
        {
            cout << "Delete " << s1[i - 1] << endl;
            i--;
        }
 
        // Add the character
        else if (dp[i][j] == dp[i][j - 1] + 1)
        {
            cout << "Add " << s2[j - 1] << endl;
            j--;
        }
    }
}
 
// Function to compute the DP matrix
void editDP(string s1, string s2)
{
    int l1 = s1.length();
    int l2 = s2.length();
    DP[l1 + 1][l2 + 1];
 
    // initialize by the maximum edits possible
    for (int i = 0; i <= l1; i++)
        DP[i][0] = i;
    for (int j = 0; j <= l2; j++)
        DP[0][j] = j;
 
    // Compute the DP matrix
    for (int i = 1; i <= l1; i++)
    {
        for (int j = 1; j <= l2; j++)
        {
            // if the characters are same
            // no changes required
            if (s1[i - 1] == s2[j - 1])
                DP[i][j] = DP[i - 1][j - 1];
            else
                // minimum of three operations possible
                DP[i][j] = min(min(DP[i - 1][j - 1],
                                   DP[i - 1][j]),
                                   DP[i][j - 1]) + 1;
        }
    }
 
    // print the steps
    printChanges(s1, s2, DP);
}
// Driver Code
int main()
{
    string s1 = "abcdef";
    string s2 = "axcdfdh";
 
    // calculate the DP matrix
    editDP(s1, s2);
 
    return 0;
}
 
// This code is contributed by
// sanjeev2552

Java

// Java program to print one possible
// way of converting a string to another
import java.util.*;
 
public class Edit_Distance {
    static int dp[][];
 
    // Function to print the steps
    static void printChanges(String s1, String s2)
    {
        int i = s1.length();
        int j = s2.length();
 
        // check till the end
        while (i != 0 && j != 0) {
 
            // if characters are same
            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                i--;
                j--;
            }
 
            // Replace
            else if (dp[i][j] == dp[i - 1][j - 1] + 1) {
                System.out.println("change " + s1.charAt(i - 1) + " to " + s2.charAt(j - 1));
                i--;
                j--;
            }
 
            // Delete the character
            else if (dp[i][j] == dp[i - 1][j] + 1) {
                System.out.println("Delete " + s1.charAt(i - 1));
                i--;
            }
 
            // Add the character
            else if (dp[i][j] == dp[i][j - 1] + 1) {
                System.out.println("Add " + s2.charAt(j - 1));
                j--;
            }
        }
    }
 
    // Function to compute the DP matrix
    static void editDP(String s1, String s2)
    {
        int l1 = s1.length();
        int l2 = s2.length();
        int[][] DP = new int[l1 + 1][l2 + 1];
 
        // initialize by the maximum edits possible
        for (int i = 0; i <= l1; i++)
            DP[i][0] = i;
        for (int j = 0; j <= l2; j++)
            DP[0][j] = j;
 
        // Compute the DP matrix
        for (int i = 1; i <= l1; i++) {
            for (int j = 1; j <= l2; j++) {
 
                // if the characters are same
                // no changes required
                if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    DP[i][j] = DP[i - 1][j - 1];
                else {
 
                    // minimum of three operations possible
                    DP[i][j] = min(DP[i - 1][j - 1],
                                   DP[i - 1][j], DP[i][j - 1])
                               + 1;
                }
            }
        }
 
        // initialize to global array
        dp = DP;
    }
 
    // Function to find the minimum of three
    static int min(int a, int b, int c)
    {
        int z = Math.min(a, b);
        return Math.min(z, c);
    }
 
    // Driver Code
    public static void main(String[] args) throws Exception
    {
        String s1 = "abcdef";
        String s2 = "axcdfdh";
 
        // calculate the DP matrix
        editDP(s1, s2);
 
        // print the steps
        printChanges(s1, s2);
    }
}

Python3

# Python3 program to print one possible
# way of converting a string to another
 
# Function to print the steps
def printChanges(s1, s2, dp):
     
    i = len(s1)
    j = len(s2)
     
   # Check till the end
    while(i > 0 and j > 0):
         
        # If characters are same
        if s1[i - 1] == s2[j - 1]:
            i -= 1
            j -= 1
             
        # Replace
        elif dp[i][j] == dp[i - 1][j - 1] + 1:
            print("change", s1[i - 1],
                      "to", s2[j - 1])
            j -= 1
            i -= 1
             
        # Delete
        elif dp[i][j] == dp[i - 1][j] + 1:
            print("Delete", s1[i - 1])
            i -= 1
             
        # Add
        elif dp[i][j] == dp[i][j - 1] + 1:
            print("Add", s2[j - 1])
            j -= 1
             
# Function to compute the DP matrix
def editDP(s1, s2):
     
    len1 = len(s1)
    len2 = len(s2)
    dp = [[0 for i in range(len2 + 1)]
             for j in range(len1 + 1)]
     
    # Initialize by the maximum edits possible
    for i in range(len1 + 1):
        dp[i][0] = i
    for j in range(len2 + 1):
        dp[0][j] = j
     
    # Compute the DP Matrix
    for i in range(1, len1 + 1):
        for j in range(1, len2 + 1):
             
            # If the characters are same
            # no changes required
            if s2[j - 1] == s1[i - 1]:
                dp[i][j] = dp[i - 1][j - 1]
                 
            # Minimum of three operations possible
            else:
                dp[i][j] = 1 + min(dp[i][j - 1],
                                   dp[i - 1][j - 1],
                                   dp[i - 1][j])
                                    
    # Print the steps
    printChanges(s1, s2, dp)
 
# Driver Code
s1 = "abcdef"
s2 = "axcdfdh"
 
# Compute the DP Matrix
editDP(s1, s2)
 
# This code is contributed by Pranav S

C#

// C# program to print one possible
// way of converting a string to another
using System;
 
public class Edit_Distance
{
    static int [,]dp;
 
    // Function to print the steps
    static void printChanges(String s1, String s2)
    {
        int i = s1.Length;
        int j = s2.Length;
 
        // check till the end
        while (i != 0 && j != 0)
        {
 
            // if characters are same
            if (s1[i - 1] == s2[j - 1])
            {
                i--;
                j--;
            }
 
            // Replace
            else if (dp[i, j] == dp[i - 1, j - 1] + 1)
            {
                Console.WriteLine("change " + s1[i - 1] + " to " + s2[j - 1]);
                i--;
                j--;
            }
 
            // Delete the character
            else if (dp[i, j] == dp[i - 1, j] + 1)
            {
                Console.WriteLine("Delete " + s1[i - 1]);
                i--;
            }
 
            // Add the character
            else if (dp[i, j] == dp[i, j - 1] + 1)
            {
                Console.WriteLine("Add " + s2[j - 1]);
                j--;
            }
        }
    }
 
    // Function to compute the DP matrix
    static void editDP(String s1, String s2)
    {
        int l1 = s1.Length;
        int l2 = s2.Length;
        int[,] DP = new int[l1 + 1, l2 + 1];
 
        // initialize by the maximum edits possible
        for (int i = 0; i <= l1; i++)
            DP[i, 0] = i;
        for (int j = 0; j <= l2; j++)
            DP[0, j] = j;
 
        // Compute the DP matrix
        for (int i = 1; i <= l1; i++)
        {
            for (int j = 1; j <= l2; j++)
            {
 
                // if the characters are same
                // no changes required
                if (s1[i - 1] == s2[j - 1])
                    DP[i, j] = DP[i - 1, j - 1];
                else
                {
 
                    // minimum of three operations possible
                    DP[i, j] = min(DP[i - 1, j - 1],
                                DP[i - 1, j], DP[i, j - 1])
                            + 1;
                }
            }
        }
 
        // initialize to global array
        dp = DP;
    }
 
    // Function to find the minimum of three
    static int min(int a, int b, int c)
    {
        int z = Math.Min(a, b);
        return Math.Min(z, c);
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        String s1 = "abcdef";
        String s2 = "axcdfdh";
 
        // calculate the DP matrix
        editDP(s1, s2);
 
        // print the steps
        printChanges(s1, s2);
    }
}
 
// This code is contributed by PrinciRaj1992
Producción: 

change f to h
change e to d
Add f
change b to x

 

Enfoque para imprimir todas las formas posibles:

Cree una colección de strings que almacenará las operaciones requeridas. Esta colección puede ser un vector de strings en C++ o una lista de strings en Java. Agregue operaciones como imprimirlas antes a esta colección. Luego cree una colección de estas colecciones que almacenará los métodos múltiples (conjuntos de operaciones de string). 
Else-if se usó anteriormente para verificar de dónde derivamos el DP[i][j]. Ahora, verifique todos los If para ver si hay más de 1 forma de obtener el elemento. Si la hubo, creamos una nueva colección desde antes, eliminamos la última operación, agregamos esta nueva operación e iniciamos otra instancia de esta función con esta nueva lista. De esta manera, agregue nuevas listas cada vez que haya un nuevo método para cambiar str1 a str2, obteniendo un nuevo método cada vez.
Al llegar al final de cualquiera de las strings, agregue esta lista a la colección de listas, completando así el conjunto de todas las operaciones posibles y agréguelas. 
A continuación se muestra la implementación del enfoque anterior: 
 

Java

// Java program to print all the possible
// steps to change a string to another
import java.util.ArrayList;
 
public class Edit_Distance {
    static int dp[][];
 
    // create List of lists that will store all sets of operations
    static ArrayList<ArrayList<String> > arrs =
                              new ArrayList<ArrayList<String> >();
 
    // Function to print all ways
    static void printAllChanges(String s1,
                                String s2, ArrayList<String> changes)
    {
 
        int i = s1.length();
        int j = s2.length();
 
        // Iterate till end
        while (true) {
 
            if (i == 0 || j == 0) {
 
                // Add this list to our List of lists.
                arrs.add(changes);
                break;
            }
 
            // If same
            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                i--;
                j--;
            }
 
            else {
                boolean if1 = false, if2 = false;
 
                // Replace
                if (dp[i][j] == dp[i - 1][j - 1] + 1) {
 
                    // Add this step
                    changes.add("Change " + s1.charAt(i - 1)
                                + " to " + s2.charAt(j - 1));
                    i--;
                    j--;
 
                    // note whether this 'if' was true.
                    if1 = true;
                }
 
                // Delete
                if (dp[i][j] == dp[i - 1][j] + 1) {
                    if (if1 == false) {
                        changes.add("Delete " + s1.charAt(i - 1));
                        i--;
                    }
                    else {
                        // If the previous method was true,
                        // create a new list as a copy of previous.
                        ArrayList<String> changes2 = new ArrayList<String>();
                        changes2.addAll(changes);
 
                        // Remove last operation
                        changes2.remove(changes.size() - 1);
 
                        // Add this new operation
                        changes2.add("Delete " + s1.charAt(i));
 
                        // initiate new new instance of this
                        // function with remaining substrings
                        printAllChanges(s1.substring(0, i),
                                        s2.substring(0, j + 1), changes2);
                    }
 
                    if2 = true;
                }
 
                // Add character step
                if (dp[i][j] == dp[i][j - 1] + 1) {
                    if (if1 == false && if2 == false) {
                        changes.add("Add " + s2.charAt(j - 1));
                        j--;
                    }
                    else {
 
                        // Add steps
                        ArrayList<String> changes2 = new ArrayList<String>();
                        changes2.addAll(changes);
                        changes2.remove(changes.size() - 1);
                        changes2.add("Add " + s2.charAt(j));
 
                        // Recursively call for the next steps
                        printAllChanges(s1.substring(0, i + 1),
                                        s2.substring(0, j), changes2);
                    }
                }
            }
        }
    }
 
    // Function to compute the DP matrix
    static void editDP(String s1, String s2)
    {
        int l1 = s1.length();
        int l2 = s2.length();
        int[][] DP = new int[l1 + 1][l2 + 1];
 
        // initialize by the maximum edits possible
        for (int i = 0; i <= l1; i++)
            DP[i][0] = i;
        for (int j = 0; j <= l2; j++)
            DP[0][j] = j;
 
        // Compute the DP matrix
        for (int i = 1; i <= l1; i++) {
            for (int j = 1; j <= l2; j++) {
 
                // if the characters are same
                // no changes required
                if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    DP[i][j] = DP[i - 1][j - 1];
                else {
 
                    // minimum of three operations possible
                    DP[i][j] = min(DP[i - 1][j - 1],
                                   DP[i - 1][j], DP[i][j - 1])
                               + 1;
                }
            }
        }
 
        // initialize to global array
        dp = DP;
    }
 
    // Function to find the minimum of three
    static int min(int a, int b, int c)
    {
        int z = Math.min(a, b);
        return Math.min(z, c);
    }
    static void printWays(String s1, String s2,
                          ArrayList<String> changes)
    {
 
        // Function to print all the ways
        printAllChanges(s1, s2, new ArrayList<String>());
 
        int i = 1;
 
        // print all the possible ways
        for (ArrayList<String> ar : arrs) {
            System.out.println("\nMethod " + i++ + " : \n");
            for (String s : ar) {
                System.out.println(s);
            }
        }
    }
 
    // Driver Code
    public static void main(String[] args) throws Exception
    {
        String s1 = "abcdef";
        String s2 = "axcdfdh";
 
        // calculate the DP matrix
        editDP(s1, s2);
 
        // Function to print all ways
        printWays(s1, s2, new ArrayList<String>());
    }
}
Producción: 

Method 1 : 

Add h
Change f to d
Change e to f
Change b to x

Method 2 : 

Change f to h
Add d
Change e to f
Change b to x

Method 3 : 

Change f to h
Change e to d
Add f
Change b to x

 

Publicación traducida automáticamente

Artículo escrito por Akarsh Rastogi 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 *