Skip to content

Instantly share code, notes, and snippets.

@Anduin2017
Created August 10, 2018 02:54
Show Gist options
  • Save Anduin2017/d3a2483a0c6509608df25b5fe6ec51f9 to your computer and use it in GitHub Desktop.
Save Anduin2017/d3a2483a0c6509608df25b5fe6ec51f9 to your computer and use it in GitHub Desktop.
Get difference from C# strings.
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