假设我有一个类
public class Audio
{
public string artist { get; set; }
public string title { get; set; }
// etc.
}
现在,我想通过相似性(不是完全匹配)条件来过滤此类音频列表中的重复项。基本上,这是勒文斯泰因距离,并通过弦的总长度进行阈值校正。问题是,关于IEqualityComparer的一般提示是“始终实现GetHashCode和Compare”。我显然无法计算GetHashCode中字符串之间的距离,因为它根本不是比较方法。但是,在这种情况下,即使是相似的音频也会返回不同的哈希值,而Distinct()会将其视为不同的对象,并且不会触发compare()方法。
我试图强制GetHashCode始终返回0,所以在collection中为每个对象调用Compare,但这很慢。所以,最后,一个问题是:.net可以直接使用.net做任何事情吗?还是应该搜索一些好的过滤算法?
最佳答案
我建议(首先)不要使用 Distinct 或 GetHashCode 。
GetHashCode 对于您的情况过于严格(如@Gabe所指出的那样)。
您可以做的是:
最终(可能有人会说)得到了一个好东西 GetHashCode 。
但是您不能像 GetHashCode 那样使用它,而应该这样使用:
bool AreSimilar(Audio me, Audio you) {
int cheapLevenshtein = Math.Abs(me.AbsoluteQuasiLevenshtein - you.AbsoluteQuasiLevenshtein);
if (cheapLevenshtein < THRESHOLD) {
int expensiveLevenshtein = Audio.LevenshteinBetween(me, you);
var result = (expensiveLevenshtein < LIMIT);
return result;
} else
return false;
}
然后,您将获得更好或更糟的算法。这只是一个想法,当然:您不能使用Distinct()。如果愿意,您可以编写自己的扩展方法,从用户程序员的角度来看,使整个过程看起来不错。
是的, AbsoluteQuasiLevenshtein 在诸如“ab”和“zy”之类的东西上是相等的,但在“ab”和“blahblahblahblah”之间却有很大的不同,至少您会优化一些东西。 ( GetHashCode + 不同的方法提出了另一个问题- GetHashCode 的严格性)。
关于c# - .net Distinct()和复杂条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15055473/