2011-04-26 41 views
0

我想要做的是收集具有属性的对象,并传入对象以充当查询模板。如何排序或优先考虑其属性值与同一类型的给定输入对象最相同的对象?如何判断列表中的哪些对象与同一类型的另一个对象最相同?

更多细节:

 List<A> myList = new List<A>() {new A() {b="x"}, 
             new A() {c="r"}, 
             new A() {b="x",c="r"},}; 

     var myTemplate = new A() {b = "x", c="r"}; 

我想这个例子相匹配,对第三个项目,但在财产cnull"f"的情况下,它应该返回的第一个和第三个项目。如果财产c"r",但bisnull"f",它应该返回第二个和第三个项目,因为它们匹配c

+0

我想你会给我们更多的细节,然后才有可能得到一个像样的答案。 – StriplingWarrior 2011-04-26 23:23:06

+0

你能给出一个你如何使用这个功能的代码示例,向我们展示一下什么需要实现? – David 2011-04-26 23:26:27

回答

1

你基本上必须拿出一个公式来确定这两个对象有多相似。为每个属性选择一个权重,然后使用简单的比较来说明该属性是否应该被视为相同。可以使用某种类型的模糊匹配,但这会变得更加复杂。

简单的东西可能是:

public byte Similarity(SomeType other) 
{ 
    byte similarity = 0; 
    if (this.Property1 == other.Property1) 
     similarity += 25; 
    if (this.Property2 == other.Property2) 
     similarity += 13; 
    if (this.Property3 == other.Property3) 
     similarity += 12; 
    if (SomeFuzzyComparisonReturnsVerySimilar(this.Property4, other.Property4)) 
     similarity += 50; 
    return similarity; 
} 

也就是说,我限定返回从0到100的数的简单方法; 100是相同的,0是完全不同的。

一旦你有了这些,选择足够相似的项目是一件相当简单的事情,你可以考虑;例如:

var similarObjects = ListOfSomeTypes.Where(s => s.Similarity(templateObject) > 75); 

或者对它们进行排序:

var sortedBySimilarity = ListOfSomeTypes.OrderByDescending(s => s.Similarity(templateObject)); 

虽然最终我的观点是,你必须要拿出自己的“共同具有最有”的定义,一旦你有剩下的可能会很容易。这并不意味着这一定很容易。

随着你的问题的更多细节,一个可能的公式是:

public byte Similarity(A other) 
{ 
    byte similarity = 0; 
    if (this.b == null | other.b == null) 
     similarity += 25; 
    else if (this.b == other.b) 
     similarity += 50; 
    if (this.c == null | other.c == null) 
     similarity += 25; 
    else if (this.c == other.c) 
     similarity += 50; 
    return similarity; 
} 

这确切的重量在一个对象略显不足匹配最高,空值和分歧都没有。

+0

嗯,我希望有一种方法来散列它,做一些通用的比较... – 2011-04-26 23:40:49

+0

我不认为哈希将工作;散列意味着独特(或尽可能接近)识别对象,即使它们具有相似的值。 – 2011-04-26 23:47:50

+0

不会有一个字符串距离算法在比较两个哈希函数吗? – 2011-04-26 23:49:53

0

我已经完成了大量数据集的大量模糊匹配,并且有很多场景需要考虑。你似乎正在接近一个简单的或通用的案例,对于那些没有大量数据的案例来说,某些通用的字符串距离比较似乎是合适的。

如果表现很重要,我最好的建议是“了解你的数据”。按照上面的建议写自己的评分。

话虽如此,我们使用Levenshtein distance进行模糊字符串匹配。就两个字符串之间的“距离”而言,它是非常不具体的,因此对于给定的问题它可能适用也可能不适用。这里是C#中算法的快速复制/粘贴。它非常容易地连接到大多数语言。这会在空输入中引发异常,因此请务必按照您的要求添加自己的特殊情况处理。

public static int LevenshteinDistance(string s, string t) 
{ 
    var sLen = s.Length; 
    var tLen = t.Length; 

    var d = new int[sLen + 1, tLen + 1]; 

    for (var i = 0; i <= sLen; d[i, 0] = i++) { } 
    for (var j = 0; j <= tLen; d[0, j] = j++) { } 

    for (var i = 1; i <= sLen; i++) 
    { 
     for (var j = 1; j <= tLen; j++) 
     { 
      var cost = (t[j - 1] == s[i - 1]) ? 0 : 1; 
      d[i, j] = Math.Min(
       Math.Min(d[i - 1, j] + 1, // a deletion 
       d[i, j - 1] + 1),   // an insertion 
       d[i - 1, j - 1] + cost); // a substitution 
     } 
    } 

    return d[sLen, tLen]; 
} 
相关问题