Created
August 10, 2018 02:54
-
-
Save Anduin2017/d3a2483a0c6509608df25b5fe6ec51f9 to your computer and use it in GitHub Desktop.
Get difference from C# strings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using Newtonsoft.Json; | |
namespace WhiteBorad | |
{ | |
public class Program | |
{ | |
private static int _ContinueStringLength = 5; | |
public static Commit GetDiff(string sourceString, string targetString) | |
{ | |
sourceString = sourceString + " "; | |
targetString = targetString + " "; | |
var commit = new Commit(); | |
int insertedFloat = 0; | |
var min = Math.Min(sourceString.Length, targetString.Length); | |
for (int i = 0; i < sourceString.Length && i+insertedFloat < targetString.Length; i++) | |
{ | |
if (sourceString[i] != targetString[i + insertedFloat]) | |
{ | |
string sourceHeader = sourceString.SafeSubstring(i, _ContinueStringLength); | |
int insertFound = targetString.IndexOf(sourceHeader, startIndex: i + insertedFloat); | |
int insertEndAt = insertFound - insertedFloat; | |
string targetHeader = targetString.SafeSubstring(i + insertedFloat, _ContinueStringLength); | |
int deleteEndAt = sourceString.IndexOf(targetHeader, i); | |
if(insertFound != -1 && deleteEndAt != -1) | |
{ | |
if(insertEndAt > deleteEndAt) | |
{ | |
insertFound = -1; | |
} | |
} | |
if (insertFound != -1 && insertEndAt > 0) | |
{ | |
var length = insertEndAt - i; | |
var insertion = new Insertion | |
{ | |
Position = i, | |
Length = length, | |
Content = targetString.Substring(i + insertedFloat, length) | |
}; | |
commit.Modifications.Add(insertion); | |
insertedFloat += insertion.Length; | |
} | |
else | |
{ | |
if(deleteEndAt == -1) | |
{ | |
deleteEndAt = sourceString.Length - _ContinueStringLength; | |
} | |
int length = deleteEndAt - i; | |
var deletion = new Deletion | |
{ | |
Position = i, | |
Length = length, | |
Content = sourceString.Substring(i, length) | |
}; | |
commit.Modifications.Add(deletion); | |
insertedFloat -= length; | |
i += length; | |
//这是一行有玄学的代码 | |
//我也不知道为什么,但是去掉它就跑不起来了 | |
if(deleteEndAt == sourceString.Length - _ContinueStringLength) | |
i--; | |
} | |
} | |
} | |
return commit; | |
} | |
public static void Test(string source, string target) | |
{ | |
var diff = GetDiff(source, target); | |
var result = diff.Apply(source); | |
if (result == target) | |
{ | |
Console.WriteLine("Passed!"); | |
} | |
else | |
{ | |
Console.WriteLine("Error!"); | |
} | |
} | |
static void Main(string[] args) | |
{ | |
//Can't match | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick brown fox jumps oveLorem ipsum dolor sit amet"); | |
//Possible mistake | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick brown fox lazy dog jumps over the lazy dog"); | |
//Did not change | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick brown fox jumps over the lazy dog"); | |
//- | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick brown fomps over the lazy dog"); | |
//+ | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick brown fox jumbbbps over the lazy dog"); | |
//-- | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The qun fox jumps over the lazy do"); | |
//-+ | |
Test( "The quick brown fox jumps over the lazy dog", | |
"Thuick brown fox jumps over the l+++++++++azy dog"); | |
//+- | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick br+++++own fox jumps ovee lazy dog"); | |
//++ | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The quick brown fox jumps over the lazy dog"); | |
//--- | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The qu brown foxmps over thy dog"); | |
//--+ | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The qbrown fox jumov+++++++er the lazy dog"); | |
//-+- | |
Test( "The quick brown fox jumps over the lazy dog", | |
"The q brown fox j++++umps over the la"); | |
//-++ | |
Test( "The quick brown fox jumps over the lazy dog", | |
"quick brown fo++x jumps over the lazy +dog"); | |
//+-- | |
Test( "The quick brown fox jumps over the lazy dog", | |
"++++++++The quick brown ov lazy dog"); | |
//+-+ | |
// Test( "The quick brown fox jumps over the lazy dog", | |
// "The quick brown fox jumps over the lazy dog"); | |
// //++- | |
// Test( "The quick brown fox jumps over the lazy dog", | |
// "The quick brown fox jumps over the lazy dog"); | |
// //+++ | |
// Test( "The quick brown fox jumps over the lazy dog", | |
// "The quick brown fox jumps over the lazy dog"); | |
} | |
} | |
public static class Library | |
{ | |
public static string SafeSubstring(this string source, int position, int length) | |
{ | |
if (source.Length >= position + length) | |
return source.Substring(position, length); | |
return source.Substring(position); | |
} | |
} | |
public class Commit | |
{ | |
public List<Modification> Modifications { get; set; } = new List<Modification>(); | |
public DateTime CommitTime { get; set; } = DateTime.Now; | |
public string Apply(string sourceString) | |
{ | |
int insertedLength = 0; | |
var resultString = sourceString; | |
foreach (var modify in Modifications) | |
{ | |
if (modify.Type == nameof(Insertion)) | |
{ | |
resultString = resultString.Substring(0, modify.Position + insertedLength) | |
+ modify.Content | |
+ resultString.Substring(modify.Position + insertedLength); | |
insertedLength += modify.Length; | |
} | |
else if (modify.Type == nameof(Deletion)) | |
{ | |
resultString = resultString.Substring(0, modify.Position + insertedLength) | |
+ resultString.Substring(modify.Position + modify.Length + insertedLength); | |
insertedLength -= modify.Length; | |
} | |
} | |
return resultString; | |
} | |
} | |
//Lorem ipsum dolor sit amet | |
//Lorem ipsum the quick fox | |
public abstract class Modification | |
{ | |
public int Position { get; set; } | |
public int Length { get; set; } | |
public string Content { get; set; } | |
public virtual string Type { get; set; } = nameof(Insertion); | |
} | |
public class Insertion : Modification | |
{ | |
public override string Type { get; set; } = nameof(Insertion); | |
} | |
public class Deletion : Modification | |
{ | |
public override string Type { get; set; } = nameof(Deletion); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment