如何在按块比较两个向量时避免重复

时间:2018-04-27 09:00:28

标签: c++ algorithm vector stl-algorithm

我试图比较两个大小为4的倍数的向量,数据用块(4个元素)表示。每个向量块都有一个唯一的编号,例如{0,0,0,0},{0,0,0,1},{0,0,0,2}或{0,0,0,0,0, 0,0,1,0,0,0,2}和{0,0,0,2,0,0,0,1}等等。我正在使用迭代器,每次增加i + = 4。我写了一个小功能来完成这项工作,但这些块往往会重复。我不确定如何删除这些块的重复。例如vector_A {0,0,0,0,0,0,0,1} vector_B {0,0,0,1,0,0,0,0,0,0,0,2}它应该给local_vector1 { 0,0,0,2}而不是我得到本地vector_1 {0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,2}

void comparing_vectors_by_block(std::vector<int> vector_A, std::vector<int> 
vector_B)
{
const int blockSize = 4;
std::vector<int> local_vector1;
std::cout << "size of the vector_A: " << vector_A.size() << std::endl;
std::cout << "size of the vector_B: " << vector_B.size() << std::endl;

for (auto it_A = std::begin(vector_A); it_A != std::end(vector_A); it_A+=4)
{
    for (auto it_B = std::begin(vector_B); it_B != std::end(vector_B); it_B += 4)
    {
        bool match = equal(it_A, it_A + blockSize, it_B, it_B + blockSize);
        if (!match)
        {
            std::cout << "match :" << std::endl;
            local_vector1.insert(local_vector1.end(), it_B, it_B + blockSize);
        }
        else
        {
            std::cout << "not matched :" << std::endl;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

使用四个int数组的向量来表示数据。 std::vector<std::array<int,4>> vect1;

如果此数据具有其他一些含义。最好使用OOP方式并创建 用于表示四个数字数据的结构或类。然后为struct / class实现operator ==和其他有用的方法。

struct foo{
    int a;
    int b;
    int c;
    ind d;
};
bool foo::operator==(const X& lhs, const X& rhs){ /* do actual comparison */ }

然后只需迭代矢量并使用==比较元素,就像传感器类型为int时一样。

for(auto& x : vector_A)
{
    if(std::find(vector_B.begin(), vector_B.end(), x) != vector_B.end()) {
         local_vector1.append(x);
    }
}

答案 1 :(得分:0)

如果我找到了你,你想得到两个块向量的对称差异。即对于A = {0,0,0,3,0,0,0,0,0,0,0,1}和B = {0,0,0,1,0,0,0,0,0, 0,0,2}你想要local_vector1 = {0,0,0,3,0,0,0,2}。

在您的实现中,您将向量A的每个块与向量B的每个块进行比较 - 当然,您将获得额外的不匹配。我的(也是非优化的)解决方案:

std::vector<int> get_blocked_vectors_diff( const std::vector<int>& vector_A, const std::vector<int>& vector_B )
{
    const int blockSize = 4;
    std::vector<int> local_vector;
    for ( auto it_A = std::begin( vector_A ); it_A != std::end( vector_A ); it_A += 4 )
    {
        bool found_in_B = false;
        for ( auto it_B = std::begin( vector_B ); !found_in_B && it_B != std::end( vector_B ); it_B += 4 )
        {
            found_in_B = std::equal( it_A, it_A + blockSize, it_B, it_B + blockSize );
        }
        if ( !found_in_B )
        {
            local_vector.insert( local_vector.end( ), it_A, it_A + blockSize );
        }
    }

    return local_vector;
}

void comparing_vectors_by_block(std::vector<int> vector_A, std::vector<int> vector_B)
{
    auto A_mines_B = get_blocked_vectors_diff( vector_A, vector_B );
    auto B_mines_A = get_blocked_vectors_diff( vector_B, vector_A );
    auto local_vector1( A_mines_B );
    local_vector1.insert( local_vector1.end(), B_mines_A.begin( ), B_mines_A.end( ) );

    for ( auto a : local_vector1 )
    {
         std::cout << a << " ";
    }
    std::cout << std::endl;
}

注意,我们需要答案的两个部分:A \ B和B \ A,因此get_blocked_vectors_diff被调用两次。

如果您像Petar Velev建议的那样更改数据结构,您将能够缩短get_blocked_vectors_diff函数:

std::vector<int> get_blocked_vectors_diff( const std::vector<Block>& vector_A, const std::vector<Block>& vector_B )
{
    std::vector<Block> local_vector;
    for ( auto& x : vector_A )
    {
        if ( std::find( vector_B.begin( ), vector_B.end( ), x ) == vector_B.end( ) )
        {
            local_vector.push_back( x );
        }
    }

    return local_vector;
}

如果首先对块的向量进行排序,可以获得更好的解决方案。