如果不准确匹配

时间:2015-06-17 09:32:44

标签: c# algorithm linq

你能帮忙吗,因为我无法找到解决问题的方法。

以下xml文档设置了按ID分组的人员记录。我想根据另外两个属性(MinAge,MaxAge)有条件地搜索节点。一切正常,我可以根据Id和年龄参数搜索特定节点。

    <Group Id="189" Description="189 T1" MinAge="20" MaxAge="30"/>
    <Group Id="189" Description="189 T2" MinAge="31" MaxAge="40"/>
    <Group Id="190" Description="190 T1" MinAge="20" MaxAge="30"/>
    <Group Id="190" Description="190 T2" MinAge="35" MaxAge="45"/>
    <Group Id="190" Description="190 T3" MinAge="49" MaxAge="50"/>
    <Group Id="191" Description="191 T1" MinAge="20" MaxAge="30"/>
    <Group Id="193" Description="193 T1" MinAge="18" MaxAge="50"/>

var allGroup = XDocument.Parse("xml string");

        var specificGroup =
            allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id &&
            int.Parse(e.Attribute("MinAge").Value) >= Age &&
            int.Parse(e.Attribute("MaxAge").Value) <= Age)

问题:如果找不到完全匹配,我想要的是返回一个紧密匹配的节点。 即, 假设我有一个Id = 189且Age为35的搜索条件,那么输出节点将是具有描述&#39; 189 T2&#39;的节点。这很好,完全匹配。

现在假设我有一个Id = 190且Age为34的搜索条件,那么因为没有匹配的记录,所以不会有任何输出节点。但在这里,

  

我想返回一个带有描述&#39; 190 T2&#39;的节点,这是紧密的   但匹配虽然不完全匹配。

2 个答案:

答案 0 :(得分:0)

只是一些经典算法:

int target = 190; // target find value
int min = int.MaxValue;
Node best = null;
foreach (var node in nodes) {
   int num = getNum(node.Describtion); // get the number from string
   if (Math.Abs(target - num) < min) {
     min = Math.Abs(target - num);
     best = node;
   }
}

这将引导您完全匹配(在这种情况下为min == 0),或者如果未找到,则会引导您到最近的年龄(更大或更小)。结果 best 节点将位于best变量中。

答案 1 :(得分:0)

这有点令人费解,但是这个应该做你想要的。

&#13;
&#13;
var specificGroup = (allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id && int.Parse(e.Attribute("MinAge").Value) <= Age &&	int.Parse(e.Attribute("MaxAge").Value) >= Age).Any()) 
						? allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id && int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value) >= Age)
						: (allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id).Any())
						? allGroup.Descendants("Group").Where(e => e.Attribute("Id").Value == Id).min(Math.Abs(Age - int.Parse(e.Attribute("MinAge").Value))+ Math.Abs(Age-int.Parse(e.Attribute("MaxAge").Value)))
						: (allGroup.Descendants("Group").Where(e => int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value >= Age)).min(Math.Abs(Id - e.Id))).Any()
						? allGroup.Descendants("Group").Where(e => int.Parse(e.Attribute("MinAge").Value) <= Age && int.Parse(e.Attribute("MaxAge").Value >= Age)).min(Math.Abs(Id - e.Id))
						: allGroup.Descendants("Group").min(e => .min(Math.Abs(Age - int.Parse(e.Attribute("MinAge").Value))+ Math.Abs(Age-int.Parse(e.Attribute("MaxAge").Value)) + Math.Abs(Id - e.Id)));
&#13;
&#13;
&#13;