|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace FuzzyString
|
|
|
|
|
{
|
|
|
|
|
public static partial class ComparisonMetrics
|
|
|
|
|
{
|
|
|
|
|
public static double JaroWinklerDistance(this string source, string target)
|
|
|
|
|
{
|
|
|
|
|
double jaroDistance = source.JaroDistance(target);
|
|
|
|
|
double commonPrefixLength = CommonPrefixLength(source, target);
|
|
|
|
|
|
|
|
|
|
return jaroDistance + (commonPrefixLength * 0.1 * (1 - jaroDistance));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double JaroWinklerDistanceWithPrefixScale(string source, string target, double p)
|
|
|
|
|
{
|
|
|
|
|
double prefixScale = 0.1;
|
|
|
|
|
|
|
|
|
|
if (p > 0.25) { prefixScale = 0.25; } // The maximu value for distance to not exceed 1
|
|
|
|
|
else if (p < 0) { prefixScale = 0; } // The Jaro Distance
|
|
|
|
|
else { prefixScale = p; }
|
|
|
|
|
|
|
|
|
|
double jaroDistance = source.JaroDistance(target);
|
|
|
|
|
double commonPrefixLength = CommonPrefixLength(source, target);
|
|
|
|
|
|
|
|
|
|
return jaroDistance + (commonPrefixLength * prefixScale * (1 - jaroDistance));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static double CommonPrefixLength(string source, string target)
|
|
|
|
|
{
|
|
|
|
|
int maximumPrefixLength = 4;
|
|
|
|
|
int commonPrefixLength = 0;
|
|
|
|
|
if (source.Length <= 4 || target.Length <= 4) { maximumPrefixLength = Math.Min(source.Length, target.Length); }
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < maximumPrefixLength; i++)
|
|
|
|
|
{
|
|
|
|
|
if (source[i].Equals(target[i])) { commonPrefixLength++; }
|
|
|
|
|
else { return commonPrefixLength; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return commonPrefixLength;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|