比较两个地图矢量

时间:2009-08-12 11:53:02

标签: c++ diff

我有两种获取大量数据的方法。数据存储在已排序的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]

这一般起作用,但如果vector1a, b, c, dvector2a, b, b1, c, d(它报告b1的断裂,{{1} }和c)。我正在使用一种算法,告诉我dvector2相比有一个额外的条目。

我想我想做一些事情,当我遇到不匹配条目时,我会查看第二个向量中的下一个条目,如果在第二个向量结束之前找到匹配项,则存储索引vector1在第二个向量中找到的条目,并移动到匹配第一个向量中的下一个条目,从i开始。

有更简洁的方法吗?我没有遇到过一些标准算法?

我正在使用C ++,因此欢迎使用C ++解决方案,但任何语言或伪代码的解决方案都会很棒。

实施例

给定任意地图对象:vector2[i+1]abcdef ;

gvector1abde

fvector2ace

我想要一个能告诉我的算法:

  

f的索引1和b的额外vector1

或(我认为这是一个有效的等效结果)

  在vector2's c != vector1's d

的索引2处

vector1's b != vector2's c和额外d

修改

我最终使用vector1,然后对两个集合中的差异进行一些匹配,以确定哪些条目相似但不同,并且其他向量中的条目完全不存在。

5 个答案:

答案 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

然后,您可以单独比较地图cc',以确定它们之间的差异。

如果您的突变和插入彼此相邻,则会变得更加复杂:

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

确定是否将VWXY匹配(或根本不匹配)是您需要为启发式设置的。

当然,如果您不关心地图内容的不同之处,那么您可以在此停止,并获得所需的输出。

答案 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中的元素不匹配,你必须添加额外的代码“无需与剩余键进行比较”。