אני יודע שיש כבר דברים מוכנים כגון אלו:
https://github.com/mmanela/diffplex/
http://git.savannah.gnu.org/cgit/diffutils.git/tree/src/analyze.c?id=fecd0079fe6e15b0f53bf953721d838d9099bf05
אבל לשם ההתלמדות חשבתי לעשות אולי משהו כזה בעצמי
הייתי שמח לקבל משוב (ההשואה יוצרת טקסט html שמסמן את השינויים)
אגב אם מישהו מכיר תוכנה כבר מוכנה (לא אתר) אשמח לשמוע עליה
להלן הקוד שלי
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TextComparer
{
public static class TextCompare
{
public static void Compare(ref string text1, ref string text2)
{
text1 = $"<span style=\"background-color: lightblue;\">{text1}</span>";
text2 = $"<span style=\"background-color: lightblue;\">{text2}</span>";
// Get the LSS lss
string lssString = "placeholdertext";
List<string> lssList = new List<string>();
string copyOfText1 = text1;
string copyOfText2 = text2;
while (!string.IsNullOrEmpty(lssString))
{
try
{
lssString = FindLongestSimilarSubstring(copyOfText1.ToCharArray(), copyOfText2.ToCharArray());
if (lssString.Length > 1) { lssList.Add(lssString); }
copyOfText2 = copyOfText2.Replace(lssString, "");
copyOfText1 = copyOfText1.Replace(lssString, "");
}
catch { break; }
}
foreach (var item in lssList)
{
text1.Replace(item, $"<span style=\"background-color: white;\"{item}");
text2.Replace(item, $"<span style=\"background-color: white;\"{item}");
}
}
static string FindLongestSimilarSubstring(char[] arr1, char[] arr2)
{
// Initialize variables to keep track of the longest common substring
int[,] table = new int[arr1.Length + 1, arr2.Length + 1];
int maxLength = 0;
int endIndex = 0;
// Fill the table
for (int i = 1; i <= arr1.Length; i++)
{
for (int j = 1; j <= arr2.Length; j++)
{
if (arr1[i - 1] == arr2[j - 1])
{
table[i, j] = table[i - 1, j - 1] + 1;
if (table[i, j] > maxLength)
{
maxLength = table[i, j];
endIndex = i - 1;
}
}
else
{
table[i, j] = 0;
}
}
}
// Extract the longest common substring
if (maxLength == 0)
{
return ""; // No common substring found
}
else
{
return new string(arr1, endIndex - maxLength + 1, maxLength);
}
}
}
}
עריכה:
לבינתיים גילית שהרעיון הנ"ל מוגבל ביותר מאחר והוא לא יכול לגלות שינויים בסדר של הקבצים מה שצריך לעשות הוא להשתמש עם lcs כמתואר כאן
https://en.wikipedia.org/wiki/Diff
מהשלא הצלחתי להבין הוא איך פותרים על ידי זה את הבעיה של מילים ששונה מיקומם. כי אפילו עם lcs עדיין אם יש אות זהה במיקום בו היתה המילה בראשונה אזי התוכנה תחשוב שהיא אותה האות למרות שבאמת היא שייכת למילה שהוזזה.
בכל אופן מצו"ב הקוד הנוכחי שלי ל-lcs
static List<string> Compare(string text1, string text2)
{
// Find the longest common subsequence
List<string> commonSubsequence = LongestCommonSubsequence(text1, text2);
// Generate diff output based on the longest common subsequence
List<string> diffOutput = GenerateDiffOutput(text1, text2, commonSubsequence);
return diffOutput;
}
private static List<string> LongestCommonSubsequence(string text1, string text2)
{
int m = text1.Length;
int n = text2.Length;
int[,] dp = new int[m + 1, n + 1];
// Build DP table
for (int i = 0; i <= m; i++)
{
for (int j = 0; j <= n; j++)
{
if (i == 0 || j == 0)
dp[i, j] = 0;
else if (text1[i - 1] == text2[j - 1])
dp[i, j] = dp[i - 1, j - 1] + 1;
else
dp[i, j] = Math.Max(dp[i - 1, j], dp[i, j - 1]);
}
}
// Reconstruct the longest common subsequence
List<string> commonSubsequence = new List<string>();
int index = dp[m, n];
int temp = index;
char[] lcs = new char[index + 1];
lcs[index] = '\0';
int p = m, q = n;
while (p > 0 && q > 0)
{
if (text1[p - 1] == text2[q - 1])
{
lcs[index - 1] = text1[p - 1];
p--;
q--;
index--;
}
else if (dp[p - 1, q] > dp[p, q - 1])
p--;
else
q--;
}
// Convert char array to List of strings
foreach (char c in lcs)
{
if (c != '\0')
commonSubsequence.Add(c.ToString());
}
return commonSubsequence;
}
private static List<string> GenerateDiffOutput(string text1, string text2, List<string> commonSubsequence)
{
List<string> diffOutput = new List<string>();
int index1 = 0, index2 = 0;
foreach (string s in commonSubsequence)
{
while (index1 < text1.Length && text1[index1].ToString() != s)
{
diffOutput.Add($"<span style=\"background-color: rgb(255, 204, 204);\">{text1[index1]}</span>");
index1++;
}
while (index2 < text2.Length && text2[index2].ToString() != s)
{
diffOutput.Add($"<span style=\"background-color: lightblue;\">{text2[index2]}</span>");
index2++;
}
diffOutput.Add($"{s}");
index1++;
index2++;
}
// Handle remaining parts of text1 and text2
for (int i = index1; i < text1.Length; i++)
{
diffOutput.Add($"<span style=\"background-color: rgb(255, 204, 204);\">{text1[i]}</span>");
}
for (int i = index2; i < text2.Length; i++)
{
diffOutput.Add($"<span style=\"background-color: lightblue;\">{text2[i]}</span>");
}
return diffOutput;
}
