在您的方案中如何定义“最相关的”? 如果你只是使用Contains,结果会错过很多“相关”的结果,这些结果与精确子串的形式不匹配。
你期待什么样的投入? 如果输入的只是一个字,那么这个算法可能会为你工作:
健身应作为 长度在 输入字符串中找到目标字符串的最长公共子 来计算,分目标字符串长度为 。例如,HPPLE 与APPLE 相比得分为0.8,因为在HPPLE中发现的APPLE 的最长子串是4个字母长, 是APPLE长度的.8。 此外,处罚由 0.1分数为每个外来字母输入串具有超过的 目标串的长度。例如。哈普勒 有得分.9相比苹果, 因为它是1个字母长, 否则有完整的子 苹果。请注意,这使得 候选词可能有 为负值。
当然还有很多其他更好的算法来计算距离。 如果输入可能包含多个单词,那么使用其他算法计算字符串之间的“距离”可能会更好。
和Umm ...你原来的查询没有结果进行排序,这样你就不会录取前7个最相关的人,你只是走前7个结果的序列。
为了总结的东西了,这可能会为你工作:
using System;
using System.Collections.Generic;
using System.Linq;
public static class StringDistanceUtil {
/// <summary>
/// Returns the longest common substring of the given two arguments.
/// </summary>
/// <param name="first">
/// the first string
/// </param>
/// <param name="second">
/// the second string
/// </param>
/// <returns>
/// the longest common substring of the given two arguments
/// </returns>
public static string LongestCommonSubstringWith(this string first, string second) {
// could have used dynamic programming, or generalized suffix tree
// to solve the LCS problem, but here we'll just stick to simplicity
var start = 0; // The start in a of the longest found so far
var len = 0; // The length of the longest found so far
for (var i = 0; i < first.Length - len; ++i) {
for (var j = first.Length - i; j > len; --j) {
if (second.Contains(first.Substring(i, j))) {
start = i;
len = j;
break; // Exit the inner loop
}
}
}
return first.Substring(start, len);
}
/// <summary>
/// Returns the distance of two strings.
/// </summary>
/// <param name="str">
/// a string
/// </param>
/// <param name="target">
/// the target string
/// </param>
/// <returns>
/// the distance from a string to the target string
/// </returns>
public static double DistanceFrom(this string str, string target) {
var strLen = str.Length;
var targetLen = target.Length;
var ratio = str.LongestCommonSubstringWith(target).Length
/(double) targetLen;
var penalty =
(strLen > targetLen) ?
(0.1 * (strLen - targetLen))
: 0;
return ratio - penalty;
}
static void Main(string[] args) {
var list = new List<string> {
"zero",
"range",
"shot",
"shoot",
"hop",
"rage",
"fang",
"age"
};
var target = "zero_range_shot";
var top5mostRelated = list
.OrderByDescending(str => str.ToUpper().DistanceFrom(target.ToUpper()))
.Take(5).ToList();
foreach (var str in top5mostRelated) Console.WriteLine(str);
}
}
,输出是: 范围 零 拍摄 拍摄 方
你还有7个结果回来? – manji 2009-11-12 10:39:30
它确实返回结果,它们只是一点点不准确 - 然后是“零”错误,这只是一个例子。许多其他名字也是如此。 如果没有很多相关的结果,我的查询只会显示相关的结果。我只是将StringComparison枚举的最大值设置为7. – CasperT 2009-11-12 10:43:08