102 lines
2.2 KiB
C#
102 lines
2.2 KiB
C#
|
|
using Godot;
|
||
|
|
|
||
|
|
using Rokojori.Extensions;
|
||
|
|
namespace Rokojori;
|
||
|
|
|
||
|
|
public class LevenshteinFuzzyMatch
|
||
|
|
{
|
||
|
|
public int lowestDistance;
|
||
|
|
public int index;
|
||
|
|
}
|
||
|
|
|
||
|
|
public class LevenshteinDistance
|
||
|
|
{
|
||
|
|
protected static int[,] GetMatrix( int aLength, int bLength )
|
||
|
|
{
|
||
|
|
var matrix = new int[ aLength + 1, bLength + 1];
|
||
|
|
|
||
|
|
|
||
|
|
for ( var i = 0; i <= aLength; i++ )
|
||
|
|
{
|
||
|
|
matrix[ i, 0 ] = i;
|
||
|
|
}
|
||
|
|
|
||
|
|
for ( var j = 0; j <= bLength; j++ )
|
||
|
|
{
|
||
|
|
matrix[ 0, j ] = j;
|
||
|
|
}
|
||
|
|
|
||
|
|
return matrix;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static LevenshteinFuzzyMatch ComputeFuzzyMatch( string value, string matcher )
|
||
|
|
{
|
||
|
|
var result = new LevenshteinFuzzyMatch();
|
||
|
|
|
||
|
|
if ( matcher.Length >= value.Length )
|
||
|
|
{
|
||
|
|
result.index = 0;
|
||
|
|
result.lowestDistance = LevenshteinDistance.Compute( value, matcher );
|
||
|
|
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
var offsets = value.Length - matcher.Length;
|
||
|
|
|
||
|
|
for ( var i = 0; i < offsets; i++ )
|
||
|
|
{
|
||
|
|
var subValue = value.Substring( i, matcher.Length );
|
||
|
|
var distance = LevenshteinDistance.Compute( subValue, matcher );
|
||
|
|
|
||
|
|
if ( i == 0 )
|
||
|
|
{
|
||
|
|
result.index = 0;
|
||
|
|
result.lowestDistance = distance;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( distance < result.lowestDistance )
|
||
|
|
{
|
||
|
|
result.index = i;
|
||
|
|
result.lowestDistance = distance;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public static int Compute( string a, string b )
|
||
|
|
{
|
||
|
|
var aLength = a.Length;
|
||
|
|
var bLength = b.Length;
|
||
|
|
|
||
|
|
if ( aLength == 0 ) { return bLength; }
|
||
|
|
if ( bLength == 0 ) { return aLength; }
|
||
|
|
|
||
|
|
var evaluationMatrix = LevenshteinDistance.GetMatrix( aLength, bLength );
|
||
|
|
|
||
|
|
for ( var i = 1; i <= aLength; i++ )
|
||
|
|
{
|
||
|
|
for ( var j = 1; j <= bLength; j++ )
|
||
|
|
{
|
||
|
|
var isSame = b[ j - 1 ] == a[ i - 1 ];
|
||
|
|
|
||
|
|
var isDifferentCost = isSame ? 0 : 1;
|
||
|
|
|
||
|
|
var insertionCost = evaluationMatrix[ i - 1, j ] + 1;
|
||
|
|
var deletionCost = evaluationMatrix[ i , j - 1 ] + 1;
|
||
|
|
var substitutionCost = evaluationMatrix[ i - 1, j - 1 ] + isDifferentCost;
|
||
|
|
|
||
|
|
evaluationMatrix[ i , j ] = Mathf.Min( Mathf.Min( insertionCost, deletionCost ), substitutionCost );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return evaluationMatrix[ aLength, bLength ];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|