【问题标题】:C# search with resemblance / affinityC# 搜索相似度/亲和力
【发布时间】:2010-11-21 07:41:03
【问题描述】:

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

我们想要列出所有与此人相似的人。 这意味着,例如,如果姓氏 affinity 超过 90 % ,则将该人添加到列表中。

例如(“安德鲁”与“安德鲁”)

最有效/最快捷的方法是什么?

遍历集合并逐个字符地比较亲和力确定?要么? 有什么想法吗?

谢谢!

【问题讨论】:

  • 根据现有的关联函数,您是在寻求帮助编写搜索,还是在编写关联函数时寻求帮助?
  • 我只是问你如何编写亲和力函数。我可以对字符进行比较。但我知道在旧 C 中有类似 mem*** ..
  • 在这种情况下,您需要仔细描述您对“亲和力”的定义,但 Ryan 在 Levenshtein Distance 上的链接应该会很有帮助。
  • 另请注意,Levenshtein 只是比较两个字符串相似度的一种方法。还有很多其他的。

标签: c# search collections


【解决方案1】:

您可能对以下内容感兴趣:

Levenshtein Distance Algorithm

Peter Norvig - How to Write a Spelling Corrector (您会对他将单词与现有单词集合进行比较的部分感兴趣)

【讨论】:

  • 是的,这就是我正在寻找的算法.. 谢谢
【解决方案2】:

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

也就是说,您必须自己实现比较逻辑,如果您想要更大程度的灵活性(或者如果您需要提高性能),您可能需要查看类似Lucene.Net 的内容。我见过和使用过的大多数文本搜索引擎都更多地基于文件,但我认为您也可以索引内存中的对象(但我不确定)。

祝你好运!

【讨论】:

    【解决方案3】:

    我不确定您是在根据现有的关联函数寻求帮助编写搜索,还是在寻求编写关联函数的帮助。所以目前我会假设你完全迷路了。

    鉴于此假设,您会注意到我将问题分为两部分,这也是您需要做的。您需要编写一个函数,该函数接受两个字符串输入并返回一个布尔值,指示输入是否足够相似。然后你需要单独搜索一个 delegate 来匹配任何具有这种签名的函数。

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

    bool IsAffinityMatch(string p1, string p2)
    

    然后您的搜索将如下所示:

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

    【讨论】:

    • 好吧,我想我没问对,但我真正需要的是那个算法。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2016-07-30
      • 2013-04-09
      • 1970-01-01
      • 2012-02-01
      • 2010-11-02
      • 2011-06-25
      • 2015-09-20
      • 2015-12-30
      • 1970-01-01
      相关资源
      最近更新 更多