使用Levenshtein Distance比较文件路径

时间:2015-12-21 23:32:22

标签: java c# algorithm comparison string-comparison

我需要弄清楚特定文件路径的接近程度,Levenshtein距离算法效果很好,但我需要以某种方式对目录树中较高的目录赋予权重。

例如:

我的来源是" x:/ t / c / d"

我的两个目标是:

  • ":/ T / C / d"
  • " X:/ T / Y / Z"

我需要第二个目标来识别更近,即使"作为一个字符串"它的编辑距离更大(因为目标2在同一个父目录中#34; x"作为源,而第一个目标正在查看目录" a"。

我如何对字符串中较早出现的字符进行加权?

3 个答案:

答案 0 :(得分:2)

在我看来,完整路径上的 Levenshtein距离并不是您想要实现的目标的正确算法。

我建议你将路径拆分成文件夹列表(最后用文件结尾),然后我会比较相应位置的目录名称(或驱动器),如果它得到高分是一个完美的匹配,当您进一步向下到目录树时降低分数。

如果它不匹配,你仍然可以在路径上应用Levenshtein距离并将其乘以一个会减少的重量,并且你会进一步下降。

总结一下。

例如:

var source = "x:/t/c/d";
var targets = new[] { "a:/t/c/d", "x:/t/y/z" };

var separator = '/';
var sourceParts = source.Split(separator);
var weight = 10;
var match = 100;

var scores = targets.Select(target =>
{
    var score = sourceParts
        .Zip(target.Split(separator), (s, t) => new Tuple<string, string>(s, t))
        .Select(
            (tuple, i) => tuple.Item1 == tuple.Item2
                ? match * GetWeight(i)
                : LevenshteinDistance(tuple.Item1, tuple.Item2) * GetWeight(i)
        ).Sum();

    return new
    {
        Target = target,
        Score = score
    };
});

其中GetWeight()类似于:

private static int MaxWeight = 10;
private static int GetWeight(int i) => i < MaxWeight ? MaxWeight - i : 1;

答案 1 :(得分:2)

如何分割源和目标usind&#34; /&#34;,然后分别比较它们中的每一个,那样第二个应该是更接近的那个

C#代码:

        var source = "x:/t/c/d";
        var sourceSplitted = source.Split('/');
        List<string> targets = new List<string>() { "a:/t/c/d", "x:/t/y/z" };

        for (int i = 0; i < sourceSplitted.Length; i++)
        {
            foreach (var item in targets)
            {
                var targetSplitted = item.Split('/');
                // Calculate levenshtein here using sourceSplitted[i] and targetSplitted[i]
            }
        }

答案 2 :(得分:1)

建议拆分路径并从后面开始给它一个反向权重,psuedocode将是:

currPath = null
currMin = int.Max


for (path in paths){ 

    var curr = 0

    var idx = 1;

    for ( x in Inverse( Split ( path ) ) ) { 

        curr+= idx * LevenshteinDistance( x )
        idx++;
    }

    if(idx < currMin)
        currPath = path;        
}

对于所有匹配的非常长的路径然后它可能不起作用但这是一个问题,你将遇到任何&#34;猜测&#34;算法,但类似的东西应该满足你的需求