コード例 #1
0
        internal static string FolderAwareEditDistance(string source, string[] targets)
        {
            if (targets.Length == 0)
            {
                return(null);
            }
            var separator     = '/';
            var sourceParts   = source.Split(separator);
            var sourceFolders = sourceParts.Reverse().Skip(1).ToList();
            var sourceFile    = sourceParts.Last();

            int missingFolderPenalty = 4;
            int extraFolderPenalty   = 3;

            var scores = targets.Select(target => {
                var targetParts   = target.Split(separator);
                var targetFolders = targetParts.Reverse().Skip(1).ToList();
                var targetFile    = targetParts.Last();

                var commonFolders        = sourceFolders.Where(x => targetFolders.Contains(x));
                var reducedSourceFolders = sourceFolders.Except(commonFolders).ToList();
                var reducedTargetFolders = targetFolders.Except(commonFolders).ToList();

                int score      = 0;
                int folderDiff = reducedSourceFolders.Count - reducedTargetFolders.Count;
                if (folderDiff > 0)
                {
                    score += folderDiff * missingFolderPenalty;
                }
                else if (folderDiff < 0)
                {
                    score += -folderDiff * extraFolderPenalty;
                }

                if (reducedSourceFolders.Count > 0 && reducedSourceFolders.Count >= reducedTargetFolders.Count)
                {
                    foreach (var item in reducedTargetFolders)
                    {
                        int min = Int32.MaxValue;
                        foreach (var item2 in reducedSourceFolders)
                        {
                            min = Math.Min(min, LevenshteinDistance.Compute(item, item2));
                        }
                        score += min;
                    }
                }
                else if (reducedSourceFolders.Count > 0)
                {
                    foreach (var item in reducedSourceFolders)
                    {
                        int min = Int32.MaxValue;
                        foreach (var item2 in reducedTargetFolders)
                        {
                            min = Math.Min(min, LevenshteinDistance.Compute(item, item2));
                        }
                        score += min;
                    }
                }
                score += LevenshteinDistance.Compute(targetFile, sourceFile);

                return(new {
                    Target = target,
                    Score = score
                });
            });
            var b = scores.OrderBy(x => x.Score);

            return(scores.OrderBy(x => x.Score).First().Target);
        }