【问题标题】:How to remove similar string from a list? [closed]如何从列表中删除类似的字符串? [关闭]
【发布时间】:2016-06-14 16:33:47
【问题描述】:

从列表中删除相似字符串的有效方法是什么?

考虑一个由这些(和其他)字符串组成的List<string>

“SRS 投资管理有限责任公司”

“SRS 投资管理”

“枫林资本有限公司”

“枫林资本有限公司”

所以我需要做的是删除“足够相似”的字符串。我的想法是,这应该通过大写列表中的所有字符串来完成,然后删除与除另一个字符串的最后 X 个字符之外的所有字符串匹配的任何字符串。最后,我希望这给我留下一个列表,其中仅包含他们实际代表的每个现实公司的一个字符串。

关于如何实现这一点的任何想法?

【问题讨论】:

  • 您应该对字符串使用 Levenshtein 距离来测量它们的接近程度,并删除某个阈值以下的任何字符串。如果你想得到导致某种全局最小值的字符串,你可能想做一些花哨的工作。这听起来并不是那么微不足道。
  • 列表中有多少项(大约)?
  • 您是否保证列表中的所有名称都具有从标准美式英语 26 字母表中提取的表示?例如,如果您需要将“Zürich Financial Services”与“Zurich Financial Services, Ltd”匹配,那么您手头的问题就比较困难了。这些字符串的第二个字符不匹配。
  • @spender 列表中大约有 10-20 个字符串
  • @EricLippert 它可能包含任何字符,还包括撇号、逗号等。

标签: c# string list


【解决方案1】:

您可以先创建一个例程,用完整的单词替换明显的缩写,然后删除空格。好消息是,Company house 对公司名称有非常严格的规定。例如,如果“Band C Ltd”已经存在,您就不能拥有一家名为“B & C Ltd”的公司。 之后,您将需要开始考虑匹配算法,例如 Levenshteins 和 Soundex。

【讨论】:

  • 我尝试替换缩写等,它似乎确实有效,尽管要替换的内容列表确实很广泛。我认为这是一个很好的起点,在使用@提出的解决方案之前查尔斯N赖斯
  • 如果您尝试匹配的是公司名称,您需要非常小心算法。我们花了数年时间开发我们的商业配对软件,每个客户都有不同的要求。我最好的建议是继续观察结果,直到找到适合单个项目的方法。
【解决方案2】:

我建议您创建一个 IEqualityComparer 来封装逻辑以确定两个字符串是否相等。

如果您想混合和匹配 SoundEx 和 Levenshtein,例如

public class CompanyNameComparer : IEqualityComparer<string>
{

    public bool Equals(string x, string y)
    {
        if (x == null && y == null)
        {
            return true;
        }
        if (x == null || y == null)
        {
            return false;
        }

        var src1 = FormatString(x);
        var src2 = FormatString(y);

        if (src1 == src2)
        {
            return true;
        }

        var difference = CalcLevenshteinDistance(src1, src2);

        // arbitrary number you will need to find what works
        return difference < 7;
    }

    private string FormatString(string source)
    {
        return source.Trim().ToUpper();
    }

    // code taken from http://stackoverflow.com/a/9453762/1798889
    private int CalcLevenshteinDistance(string a, string b)
    {
       // code not included 
    }

    public int GetHashCode(string obj)
    {
        return Soundex(obj).GetHashCode();
    }

    private string Soundex(string data)
    {
        // code not included 
    }
}

我没有包含所有代码,因为这不是重点。只有您会知道 SoundEx 和 Levenshtein 是否可以工作,或者是否需要其他东西。但是,如果您将决策放在它自己的类中,如果需要对其进行调整,那么它只是需要更改的地方。

然后您可以使用 Linq 或 HashSet 获得唯一列表。假设数据是您的列表变量的名称

var uniqueEnumerable = data.Distinct(new CompanyNameComparer());
var uniqueSet = new HashSet<string>(data, new CompanyNameComparer());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-17
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 2021-12-09
    • 2019-02-12
    • 1970-01-01
    相关资源
    最近更新 更多