我有一个包含以下字段的文档:
我有以下表结构:
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。
当然,您可以检查每一列并保持匹配的行打开,直到您循环每一行。 但是,这个表结构可能变得非常大,我正在寻找一种能够以高效和良好的方式解决上述问题的算法。
有什么想法吗?
答案 0 :(得分: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
值作为键,而hastables作为值。这些哈希表以field2
为键,result
为值。由于您允许null
作为值,因此您必须使用HashMap
而不是Hashtable
。
答案 1 :(得分:0)
对于像这样的任何字符串搜索,最快的选项是基数树。创建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;
}