Diff comparison word by word and display changes

255 Views Asked by At

Could be marked as duplicated, but I haven't found a propper solution yet.

I need to write a function that compares 2 pieces of text word by word, and prints out the text showing added/deleted/changed words. For example:

StringOriginal = "I am Tim and I am 27 years old"

StringEdited = "I am Kim and I am not that old".

Result: I am Tim Kim and I am 27 years not that old.

Most of the diff algorithms I find tend to compare char by char. this works fine, untill you have a 2 different words on the same index, with mutual chars.

"I am Tim" edited to "I am Kim" Results into:

I am TKim

instead of

I am Tim Kim.

Any pointers?

4

There are 4 best solutions below

1
proxies On

Split by space both StringOriginal and StringEdited. Loop thru each word of StringOriginal comparing it to the same word index from Edited. Every unequal word should be put to a temporary variable and concatenate it to the result only when you get equal word again from the loop. Use StringBuilder in creating the result. Hope this helps

0
LocEngineer On

Split both strings by space, join the resulting arrays via Union, then back to string like this:

string[] arr1 = str1.Split(' ');
string[] arr2 = str1.Split(' ');

var merged = arr1.Union(arr2).ToArray<string>();

var mergedString = string.Join(' ', merged);
1
Serkan Arslan On

little bit old fashion, but you can try this.

    string StringOriginal = "I am Tim and I am 27 years old";
    string StringEdited = "I am Kim and I am not that old";

    string[] StringOriginalArray = StringOriginal.Split();
    string[] StringEditedArray = StringEdited.Split();
    string[] newStringArray = new string[StringOriginalArray.Length + StringEditedArray.Length];

    int i = 0;
    int io = 0;
    int ie = 0;

    while (i < newStringArray.Length)
    {
        if (io < StringOriginalArray.Length)
        {
            newStringArray[i] = StringOriginalArray[io];
            io++;
            i++;
        }
        if (ie < StringEditedArray.Length)
        {
            newStringArray[i] = StringEditedArray[ie];
            ie++;
            i++;
        }
    }

    string[] finalArray = new string[newStringArray.Length];
    int f = 0;
    for (int k = 0; k < newStringArray.Length; k=k+2)
    {
        finalArray[f++] = newStringArray[k];
        if (newStringArray[k] != newStringArray[k+1])
        {
            finalArray[f++] = newStringArray[k+1];
        }
    }

    Console.WriteLine(String.Join(" ", finalArray));

Output:

"I am Tim Kim and I am 27 not years that old"
0
Dĵ ΝιΓΞΗΛψΚ On

been looking for an answer myself to this question. haven't been able to find a good solution. came up with the following. but it's not perfect.

    public static class DiffEngine
    {
        private static Regex r = new Regex(@"(?<=[\s])", RegexOptions.Compiled);

        public static string Process(ref string TextA, ref string TextB)
        {
            var A = r.Split(TextA);
            var B = r.Split(TextB);
            var max = Math.Max(A.Count(), B.Count());
            var sbDel = new StringBuilder("<del>");
            var sbIns = new StringBuilder("<ins>");
            var sbOutput = new StringBuilder();
            var aCurr = string.Empty;
            var bCurr = string.Empty;
            var aNext = string.Empty;
            var bNext = string.Empty;

            for (int i = 0; i < max; i++)
            {
                aCurr = (i > A.Count() - 1) ? string.Empty : A[i];
                bCurr = (i > B.Count() - 1) ? string.Empty : B[i];
                aNext = (i > A.Count() - 2) ? string.Empty : A[i + 1];
                bNext = (i > B.Count() - 2) ? string.Empty : B[i + 1];

                if (aCurr == bCurr)
                {
                    sbOutput.Append(aCurr);
                }
                else
                {
                    if (aNext != bNext)
                    {
                        sbDel.Append(aCurr);
                        sbIns.Append(bCurr);
                    }
                    else
                    {
                        sbDel.Append(aCurr);
                        sbIns.Append(bCurr);
                        sbOutput
                            .Append(sbDel.ToString())
                            .Append("</del>")
                            .Append(sbIns.ToString())
                            .Append("</ins>");
                        sbDel.Clear().Append("<del>");
                        sbIns.Clear().Append("<ins>");
                    }
                }
            }

            A = null;
            B = null;
            sbDel = null;
            sbIns = null;
            return sbOutput.ToString();

        }
    }