Print all possible ways to convert one string into another string | Edit-Distance - GeeksforGeeks

23 Apr, 2021
Prerequisite: Dynamic Programming | Set 5 (Edit Distance) Given two strings str1 and str2, the task is to print the all possible ways to convert ‘str1’ into ‘str2’. Below are the operations that can be performed on “str1”:  
InsertRemoveReplace
Insert
Remove
Replace
All of the above operations are of equal cost. The task is to print all the various ways to convert ‘str1’ into ‘str2’ using the minimum number of edits (operations) required, where a “way” comprises of the series of all such operations required. Examples:  
Input: str1 = “abcdef”, str2 = “axcdfdh” Output: Method 1: Add h Change f to d Change e to f Change b to xMethod 2: Change f to h Add d Change e to f Change b to xMethod 3: Change f to h Change e to d Add f Change b to x  
 
Approach for printing one possible way:
The approach for finding the minimum number of edits has been discussed in this post. To print one possible way, iterate from the bottom right corner of the DP matrix formed using Min-Edit Distance method. Check if the character pertaining to that element in both strings is equal or not. If it is, it means it needs no edit, and DP[i][j] was copied from DP[i-1][j-1].  
If str1[i-1] == str2[j-1], proceed diagonally. 
Note that since the DP matrix contains one extra row and column at 0 indices, String indexes will be decreased by one. i.e. DP[i][j] corresponds to i-1 index of str1 and j-1 index of str2.Now, if the characters were not equal, that means this matrix element DP[i][j] was obtained from the minimum of DP[i-1][j-1], DP[i][j-1] and DP[i-1][j], plus 1. Hence, check from where this element was from.  
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.
Once the end i.e., (i==0 or j==0 ) of either string is reached, converting of one string to other is done. We will have printed all the set of operations required. Below is the implementation of the above approach:  
C++
Java
Python3
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 stepsvoid 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 matrixvoid 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 Codeint main(){    string s1 = "abcdef";    string s2 = "axcdfdh";     // calculate the DP matrix    editDP(s1, s2);     return 0;} // This code is contributed by// sanjeev2552
// Java program to print one possible// way of converting a string to anotherimport 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 program to print one possible# way of converting a string to another # Function to print the stepsdef 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 matrixdef 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 Codes1 = "abcdef"s2 = "axcdfdh" # Compute the DP MatrixeditDP(s1, s2) # This code is contributed by Pranav S
// C# program to print one possible// way of converting a string to anotherusing 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                {                     // minimu 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
change f to h
change e to d
Add f
change b to x
 
Approach to print all possible ways:
Create a collection of strings that will store the operations required. This collection can be a vector of strings in C++ or a List of strings in Java. Add operations just like printing them before to this collection. Then create a collection of these collections which will store the multiple methods (sets of string operations). Else-if was used earlier to check from where we derived the DP[i][j] from. Now, check all If’s to see if there were more than 1 ways you could obtain the element. If there was, we create a new collection from before, remove the last operation, add this new operation and initiate another instance of this function with this new list. In this manner, add new lists whenever there was a new method to change str1 to str2, getting a new method every time.On reaching the end of either string, add this list to the collection of lists, thus completing the set of all possible operations, and add them. Below is the implementation of the above approach:  
Java
// Java program to print all the possible// steps to change a string to anotherimport 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>());    }}
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
 
sanjeev2552
princiraj1992
pranav1503
sweetyty
arorakashish0911
Algorithms-Recursion
Java-ArrayList
Java-Strings
Dynamic Programming
Java-Strings
Dynamic Programming
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Subset Sum Problem | DP-25
Matrix Chain Multiplication | DP-8
Longest Palindromic Substring | Set 1
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Sieve of Eratosthenes
Overlapping Subproblems Property in Dynamic Programming | DP-1
Cutting a Rod | DP-13
Longest Common Substring | DP-29