我有两种获取大量数据的方法。数据存储在已排序的vector<map<string, int> >
。
我想确定两个载体之间是否存在不一致。
我目前正在做什么(伪代码):
for i in 0... min(length(vector1), length(vector2)):
for (k, v) in vector1[i]:
if v != vector2[i][k]:
// report that k is bad for index i,
// with vector1 having v, vector2 having vector2[i][k]
for i in 0... min(length(vector1), length(vector2)):
for (k, v) in vector2[i]:
if v != vector1[i][k]:
// report that k is bad for index i,
// with vector2 having v, vector1 having vector1[i][k]
这一般起作用,但如果vector1
有a, b, c, d
且vector2
有a, b, b1, c, d
(它报告b1
的断裂,{{1} }和c
)。我正在使用一种算法,告诉我d
与vector2
相比有一个额外的条目。
我想我想做一些事情,当我遇到不匹配条目时,我会查看第二个向量中的下一个条目,如果在第二个向量结束之前找到匹配项,则存储索引vector1
在第二个向量中找到的条目,并移动到匹配第一个向量中的下一个条目,从i
开始。
有更简洁的方法吗?我没有遇到过一些标准算法?
我正在使用C ++,因此欢迎使用C ++解决方案,但任何语言或伪代码的解决方案都会很棒。
给定任意地图对象:vector2[i+1]
,a
,b
,c
,d
,e
和f
;
g
:vector1
,a
,b
,d
,e
和f
:vector2
,a
,c
,e
我想要一个能告诉我的算法:
f
的索引1和b
的额外vector1
。
或(我认为这是一个有效的等效结果)
在vector2's c != vector1's d
的索引2处
vector1's b != vector2's c
和额外d
我最终使用vector1
,然后对两个集合中的差异进行一些匹配,以确定哪些条目相似但不同,并且其他向量中的条目完全不存在。
答案 0 :(得分:4)
类似于std::mismatch算法
您也可以使用std::set_difference
答案 1 :(得分:1)
听起来你正在寻找diff算法。想法是识别两个向量的longest common subsequence(使用映射相等),然后递归非公共部分。最终,您将拥有相同的矢量子序列的交替列表,以及没有共同元素的子序列。然后,您可以轻松地从中生成任何您喜欢的输出。
将它应用于两个向量,然后就可以了。
请注意,由于地图比较费用昂贵,如果您可以对地图进行哈希处理(使用强哈希 - 冲突会导致输出错误)并使用哈希进行比较,则可以节省大量时间。
一旦你在最后得到不匹配的子序列,你会有类似的东西:
Input vectors: a b c d e f, a b c' d e f
Output:
COMMON a b
LEFT c
RIGHT c'
COMMON d e f
然后,您可以单独比较地图c
和c'
,以确定它们之间的差异。
如果您的突变和插入彼此相邻,则会变得更加复杂:
Input vectors: a b V W d e f, a b X Y d e f
Output:
COMMON a b
LEFT V W
RIGHT X Y
COMMON d e f
确定是否将V
和W
与X
或Y
匹配(或根本不匹配)是您需要为启发式设置的。
当然,如果您不关心地图内容的不同之处,那么您可以在此停止,并获得所需的输出。
答案 2 :(得分:0)
你到底想要达到什么目的?您能否准确定义您对输入的预期输出?您的伪代码会比较矢量索引处的地图。如果那不是正确的语义,那么是什么?
答案 3 :(得分:0)
你能否将每张地图与某种校验和(或布鲁门滤波器)联系起来 - 在单次检查时你可以决定比较是否有意义。
答案 4 :(得分:0)
在您的示例中,请注意无法区分
vector1的索引1处的额外b,和 vector2的c!= vector1的d。
和
向量1的索引1处的额外b,额外 d在v1的索引2处,而在c处的额外c处 在v2中
因为不清楚将“c”与“d”进行比较,所以可以将其与“b”进行比较。我假设向量没有排序,因为std :: map不提供关系运算符。相反是地图,就我看来完全无关紧要;-) 所以你的例子有点误读。它甚至可能是
比较 b f e a d
与 a c f e
您可以针对第二个向量的每个元素检查第一个向量的每个元素。 这有二次运行时间。
for i in 0... length(vector1):
foundmatch = false;
for j in 0... length(vector2):
mismatch = false;
for (k, v) in vector1[i]:
if v != vector2[j][k]:
mismatch = true;
break; // no need to compare against the remaining keys.
if (!mismatch) // found matching element j in vector2 for element i in vector1
foundmatch = true;
break; // no need to compare against the remaining elements in vector2
if (foundmatch)
continue;
else
// report that vector1[i] has no matching element in vector2[]
// "extra b at i"
如果你想找到缺少的元素,只需交换vector1和vector2。
如果你想只在一个键中检查vector2中的一个元素与vector1中的元素不匹配,你必须添加额外的代码“无需与剩余键进行比较”。