【问题标题】:How to avoid repetitions when comparing two vectors by blocks按块比较两个向量时如何避免重复
【发布时间】:2018-04-27 09:00:28
【问题描述】:

我正在尝试比较两个大小为 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 的迭代器。我写了一个小函数来完成这项工作,但块往往会重复。我不确定如何 t0 删除这些块的重复。例如 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;
        }
    }
}

【问题讨论】:

  • 如果你有一个“块”向量,为什么不将它制作一个实际的“块”向量,就像一个数组向量(例如std::vector&lt;std::array&lt;int, 4&gt;&gt;)?然后比较就变成了普通的==比较运算符。
  • 为什么不匹配就输出“match:”,匹配就输出“not match”?
  • 我不确定数组向量是如何工作的。我会看一看。这似乎是一个合理的解决方案。
  • 匹配和不匹配只是为了调试。请忽略。

标签: c++ algorithm vector stl-algorithm


【解决方案1】:

使用由四个整数组成的数组向量来表示数据。 std::vector&lt;std::array&lt;int,4&gt;&gt; vect1;

如果这个数据有其他含义。最好使用OOP方式并创建 一个结构或一个类来表示这四个数字数据。然后为结构/类实现运算符== 和其他有用的方法。

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);
    }
}

【讨论】:

    【解决方案2】:

    如果我没听错,你想得到两个块向量的对称差。 IE。对于 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;
    }
    

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

    【讨论】:

    • 谢谢。现在很清楚了。我将使用适当的数据结构来实现它。
    猜你喜欢
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    • 2014-12-20
    • 2016-01-23
    • 1970-01-01
    相关资源
    最近更新 更多