在您的方案中如何定義「最相關的」? 如果你只是使用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