具有相似性/亲和力的C#搜索

时间:2009-08-20 13:01:27

标签: c# search collections

假设我们有一个IEnumerable Collection 20 000人对象项。 然后假设我们创建了另一个Person对象。

我们要列出重新组合此人的所有人员。 这意味着,例如,如果姓氏亲和力超过90%,请将该人员添加到列表中。

e.g。 (“安德鲁”与“安德鲁”)

这样做最有效/最快捷的方式是什么?

迭代整个集合并将char与char进行比较并进行亲和力测定?要么? 有什么想法吗?

谢谢!

4 个答案:

答案 0 :(得分:6)

您可能感兴趣:

Levenshtein Distance Algorithm

Peter Norvig - How to Write a Spelling Corrector (你会对他将一个单词与一系列现有单词进行比较的部分感兴趣)

答案 1 :(得分:1)

根据您需要进行此搜索的频率,强力迭代和比较方法可能足够快。实际上有两万条记录并不是那么多,除非请求数量很大,否则您的性能可能是可以接受的。

那就是说,你必须自己实现比较逻辑,如果你想要很大程度的灵活性(或者如果你需要发现你必须处理性能),你可能想看看像{{3}这样的东西。 }。我见过和使用的大多数文本搜索引擎都是基于文件的,但我认为你也可以索引内存中的对象(但我不确定)。

祝你好运!

答案 2 :(得分:1)

我不确定你是否在寻求帮助时根据你现有的亲和功能编写搜索,或者你是否要求帮助编写亲和功能。所以暂时我会假设你完全迷失了。

考虑到这个假设,你会注意到我把问题分成两部分,这也是你需要做的事情。您需要编写一个带有两个字符串输入的函数,并返回一个布尔值,指示输入是否足够相似。然后,您需要单独搜索委托,它将匹配具有该类签名的任何函数。

亲和力函数的基本签名可能如下所示:

bool IsAffinityMatch(string p1, string p2)

然后你的搜索会是这样的:

MyPersonCollection.Where(p => IsAffinityMatch(p.Surname, OtherPerson.Surname));

答案 3 :(得分:1)

我提供了该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个字符串相同。