【问题标题】:Algorithm to quickly find a row in a table快速查找表中一行的算法
【发布时间】:2012-10-31 09:12:03
【问题描述】:

我有一个包含以下字段的文档:

  • 字段1
  • 字段2
  • 字段3
  • 字段4

我的表结构如下:

field1  |  field2  |  field3  |  field4  || result
--------------------------------------------------
foo                   bar                   MC
foo        test1                            MR
           test2                 test3      OM
foo        test1      bar                   CM

当一个文档进来,field1是foo,field2(空值),field3是bar,应该选择结果MC。 当一个文档进来,field1是foo,field2是test1,field3是bar,应该选择结果CM。

当然,您可以检查每一列并将匹配的行保持打开状态,直到您循环每一行。 但是,这个表结构可能会变得非常大,我正在寻找某种算法来解决上述问题,以一种高性能且良好的方式。

有什么想法吗?

【问题讨论】:

  • “文档”是什么意思?这是文本/普通文件吗?此类文件的内容是否总是与您的示例类似?
  • field1等的值是否受限?
  • 这个问题已经解决了 50 年,结果就是今天的 RDBMS。如果您想实现自己的,只需复制这些解决方案即可。
  • @Tichodroma:文档是带有字段列表的 Java 对象 List
  • @vainolo:field1的值没有限制,可以取任何值

标签: java algorithm design-patterns


【解决方案1】:

正如@MarkoTopolnik 所写,RDBMS 可以做您想做的事情。但是如果你仍然想实现你自己的算法,一个选择是创建一个树:级别 1 是field1,级别 2 是field2,等等。每个分支是你表的一行。如果您只有两个字段,则如下所示:

root----field1.valueA----field2.valueC---result1
    \                \
     \                \--field2.valueD---result2
      \
       \field1.valueB----field2.valueC---result3
                     \
                      \--field2.valueD---result4

您可以在每个级别使用哈希表来实现此树。首先,您有一个哈希表,其中 field1 值作为键,哈希表作为值。这些哈希表有field2 作为键和result 作为值。由于您允许 null 作为值,因此您必须使用 HashMap 而不是 Hashtable

【讨论】:

    【解决方案2】:

    对于任何这样的字符串搜索,最快的选择是基数树。创建 4 根基数树,每个字段的叶子是值参与的记录的排序列表。例如,对于字段 1,如果您在 Foo 上搜索,它应该返回一个类似于 { 1, 2, 4 } 表示 Foo 在字段 1 的记录 1、2 和 4 中。结果是你将有 4 组数字,它们的交集就是答案。

    要获得交点可以在线性时间内完成,因为它们是按排序顺序维护的。这是一个在 C 中执行此操作的简单排序集合交集算法:

    #define int32 unsigned int
    
    // A, B - operands, sorted arrays
    // s_a, s_b - sizes of A and B
    // C - result buffer
    // return size of the result C
    size_t intersect_sorted_list(int32 *A, int32 *B, size_t s_a, size_t s_b, int32 *C) {
        size_t i_a = 0, i_b = 0;
        size_t counter = 0;
    
        while(i_a < s_a && i_b < s_b) {
            if(A[i_a] < B[i_b]) {
                i_a++;
            } else if(B[i_b] < A[i_a]) {
                i_b++;
            } else {
                C[counter++] = A[i_a];
                i_a++; i_b++;
            }
        }
        return counter;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多