[英]C# search with resemblance / affinity
假設我們有一個帶有20 000 Person對象項的IEnumerable Collection
。 然后假設我們創建了另一個Person對象。
我們想列出重新組合此人的所有人員。 這意味着,例如,如果Surname 親緣關系超過90% ,請將該Person添加到列表中。
例如(“安德魯”vs“安德魯”)
這樣做最有效/最快捷的方法是什么?
迭代集合並將char與char進行比較並進行親和力測定? 要么? 有任何想法嗎?
謝謝!
根據您需要進行此搜索的頻率,強制迭代和比較方法可能足夠快。 實際上有兩萬條記錄並不是那么多,除非請求數量很大,否則您的性能可能是可以接受的。
也就是說,你必須自己實現比較邏輯,如果你想要很大程度的靈活性(或者如果你需要發現你必須處理性能),你可能想看看像Lucene.Net這樣的東西。 我見過和使用的大多數文本搜索引擎都是基於文件的,但我認為你也可以索引內存中的對象(但我不確定)。
祝好運!
鑒於您現有的親和功能,或者您正在尋求幫助編寫親和功能,我不確定您是否在尋求幫助來編寫搜索。 所以暫時我會假設你完全迷失了。
鑒於這種假設,你會注意到我將問題分成兩部分,這也是你需要做的事情。 您需要編寫一個帶有兩個字符串輸入的函數,並返回一個布爾值,指示輸入是否足夠相似。 然后,您需要一個單獨的搜索委托 ,該委托將匹配具有該類簽名的任何函數。
親和力函數的基本簽名可能如下所示:
bool IsAffinityMatch(string p1, string p2)
然后你的搜索看起來像這樣:
MyPersonCollection.Where(p => IsAffinityMatch(p.Surname, OtherPerson.Surname));
我提供了Affinity方法的源代碼:
/// <summary>
/// Compute Levenshtein distance according to the Levenshtein Distance Algorithm
/// </summary>
/// <param name="s">String 1</param>
/// <param name="t">String 2</param>
/// <returns>Distance between the two strings.
/// The larger the number, the bigger the difference.
/// </returns>
private static int Compare(string s, string t)
{
/* if both string are not set, its uncomparable. But others fields can still match! */
if (string.IsNullOrEmpty(s) && string.IsNullOrEmpty(t)) return 0;
/* if one string has value and the other one hasn't, it's definitely not match */
if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(t)) return -1;
s = s.ToUpper().Trim();
t = t.ToUpper().Trim();
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
int cost;
if (n == 0) return m;
if (m == 0) return n;
for (int i = 0; i <= n; d[i, 0] = i++) ;
for (int j = 0; j <= m; d[0, j] = j++) ;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cost = (t.Substring(j - 1, 1) == s.Substring(i - 1, 1) ? 0 : 1);
d[i, j] = System.Math.Min(System.Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
return d[n, m];
}
這意味着,如果返回0,則2個字符串是相同的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.