用于查找给定输入集的匹配集的算法

时间:2013-09-10 09:05:57

标签: .net algorithm

我有一组输入集,每个元素最多包含50个字符。可以想象一个带有varchar(50)列的数据库表,每一行都是一个输入集。列数通常在5-8范围内。行数通常约为2-3百万,但最多可达1.5亿。每列必须具有非空值。我们将这个表称为T,并将其每行RT

我有第二组输入,表示匹配模式。就像原始输入一样,它也可以被认为是具有相同固定列数的数据库表(加上用于匹配目标的元数据,但该部分不相关)。但是,这次只有一列必须有一个值,但其中任何一列都可以为null。我们称这个表为M,并且每行RM。该表的典型大小为4000 - 5000行,但最高可达40 000。

这里的任务是针对每个RT,我们必须找到匹配的RM。以下是给定RT的匹配规则:

  1. 如果RM的所有元素与RT中的相应元素相同,则进行匹配。 (字符串完全匹配被认为是相同的)。如果RM中的元素为空,则不检查RT是否匹配。

  2. 只能进行一场比赛。如果识别出多个匹配,则具有最长RM的那个匹配被认为是正确的匹配。这里可以忽略具有相同长度的多个RM的情况。我们只选择第一个确定的。

  3. 代码将在具有4 GB RAM的典型Windows客户端上运行。因此,MT可以保存在内存中,但T不能。

    我正在寻找一种减少比较次数的技术。更具体地说,您是否了解一种技术,可以针对给定的RT检查整个MT。如果没有,处理这个问题的最有效方法是什么?

    这将在.NET中编码,并且非常感谢.NET的任何现有代码或库。

    谢谢,

    凯末尔

    注意:

    1. 这不是作业。我大约20年前毕业:)

    2. 正则表达式RM存在此问题的变体。但对于当前版本,与简单字符串等效的匹配就足够了。

    3. 以下是一些例子:

    4. RT = {A,B,C,D,E}

      RM1 = {A ,,,,} RM2 = {A,B ,,,} RM3 = {A ,,, D,E}

      对于此RT,所有这些都匹配。但由于规则2,我们选择RM3作为匹配。希望这个例子澄清

      1. T数据实际上不在db中。它有多种格式,包括excel,text,xml和一些统计SW原生数据文件。我们有一个数据管道结构,可以动态读取原生格式的数据并保留游标。 RT是该游标的一部分,只是一个字符串数组

1 个答案:

答案 0 :(得分:0)

解决方案应该涉及某种匹配树。目标是遍历每个RT的树,直到到达叶节点,此时您可能有几个匹配,但其中一个匹配是最好的。树中的节点是匹配(可能是部分匹配,如{A,,,D,}),如果满足节点匹配,算法将落入一个分支或另一个分支。

实现这一目标的方法不止一种,首先要选择一种方法来决定你的速度有多快。需要考虑的一件事是空间局部性,因为对于一个大的非优化树算法,它会像一只勇敢的兔子一样在内存中跳跃,并完全忽视内存缓存的好处。

让我们假设二叉树足够好。如果满足匹配则算法遵循左分支,否则算法右分支。因此,对于您的情况,根节点匹配{A,,,,},并且完整树如下(每个节点尝试匹配某些内容,如果找到匹配则具有分支y>并且分支n>如果没有匹配:

{A,,,,}
 y> {,B,,,}
  y> out, matching {A,B,,,}
  n> {,,,D,E}
   y> out, matching {A,,,D,E}
   n> out, matching {A,,,,}
 n> out, no match

从M表编译这个匹配树本身就是一个问题。您应该考虑T表中项目的统计出现,以便在大多数RT中尽可能快地遍历树。