如何交错两个不同大小的向量?

How to interleave two vectors of different sizes?

我有两个向量

vector<int> first_v = {1, 4, 9, 16, 8, 56};
vector<int> second_v = {20, 30};

目标是以特定顺序组合这些向量(基本上程序首先打印 first_v 向量的一个值,然后打印 second_v 向量的一个值):

Expected Output:
1 20 4 30 9 16 8 56

我非常接近解决方案,但问题是如果一个向量比另一个短,程序将打印“0”。

Problem output:
1 20 4 30 9 0 16 0

这是我试图解决这个问题的代码

merge_vect(first_v, second_v);

vector<int> merge_vect(const vector<int> & a, const vector<int> & b){
  vector<int> vec(a.size() + b.size());

  for (int i = 0; i < vec.size(); i++){
    cout << a[i] << " ";
    cout << b[i] << " ";
  }  
  return vec;
}

我该怎么做才能解决这个问题?

您可以为每个向量保留一个迭代器,并从尚未到达其 end() 迭代器的向量中添加。

示例:

#include <iostream>
#include <vector>

std::vector<int> merge_vect(const std::vector<int>& avec,
                            const std::vector<int>& bvec)
{
    std::vector<int> result;
    result.reserve(avec.size() + bvec.size());

    for(auto ait = avec.begin(), bit = bvec.begin();
        ait != avec.end() || bit != bvec.end();) 
    {
        if(ait != avec.end()) result.push_back(*ait++);
        if(bit != bvec.end()) result.push_back(*bit++);
    }

    return result;
}

int main() {
    std::vector<int> first_v = {1, 4, 9, 16, 8, 56};
    std::vector<int> second_v = {20, 30};

    auto result = merge_vect(first_v, second_v);

    for(auto val : result) std::cout << val << ' ';
}

输出:

1 20 4 30 9 16 8 56 

一种可能的优化方法是从两个向量中复制,只要它们都有元素,然后一次性从较大的向量中复制其余部分:

std::vector<int> merge_vect(const std::vector<int>& avec,
                            const std::vector<int>& bvec)
{
    std::vector<int> result;
    result.reserve(avec.size() + bvec.size());
    auto ait = avec.begin(), bit = bvec.begin();
    
    // copy while both have more elements:
    for(; ait != avec.end() && bit != bvec.end(); ++ait, ++bit) {
        result.push_back(*ait);
        result.push_back(*bit);
    }

    // copy the rest
    if(ait != avec.end()) result.insert(result.end(), ait, avec.end());
    else if(bit != bvec.end()) result.insert(result.end(), bit, bvec.end());

    return result;
}