【问题标题】:Error while concatenating a vector to itself in c++在c ++中将向量连接到自身时出错
【发布时间】:2022-01-08 16:46:37
【问题描述】:

我只是想将一个向量连接到自身,但以下代码不起作用,我无法找到问题所在。如果我的输入向量是 {1,2,1},我得到的 o/p 是 {1,2,1,1,16842944,1}。请告诉我哪里错了。我想要的输出是 [1,2,1,1,2,1]

 vector<int> getConcatenation(vector<int>& nums) {
        
        int size=nums.size();
        auto itr=nums.begin();

        while(size--)
        {

            nums.push_back(*itr);
             itr++;
        }
        
        return nums;      
    }

【问题讨论】:

  • 了解迭代器失效。 如果新的 size() 大于 capacity(),则所有迭代器和引用(包括过去的迭代器)都将失效。
  • 你可以简读here
  • 如果vector需要更新容量,那么所有的迭代器都会失效。您需要另一种连接元素的方法。
  • push_back 可以使所有迭代器失效。 en.cppreference.com/w/cpp/container/vector/push_back 您可以使用索引或保留足够的空间,因此不需要重新分配。
  • 简单的解决方案一:对循环使用索引而不是迭代器。简单的解决方案二:Reserve内存所以容量会在循环之前设置。

标签: c++ c++11 vector std stdvector


【解决方案1】:

正如已经彻底指出的那样,问题在于向量在进行修改时会重新分配其存储空间。至少有三种通用方法。

首先,使用索引而不是迭代器:

vector<int> getConcatenation(vector<int>& nums) {
    int size = nums.size();
    for (int i = 0; i < size; ++i)
        nums.push_back(nums[i]);
    return nums;
}

其次,使用迭代器但确保向量不必重新分配:

vector<int> getConcatenation(vector<int>& nums) {
    int size = nums.size();
    nums.reserve(2 * size);
    auto itr = nums.begin();
    while (--size)
        nums.push_back(*itr++);
    return nums;
}

(这种方法包括劳动密集型较少的事情,例如使用基于迭代器进行复制的内置算法)

第三,除非您必须修改输入参数,否则只需构建一个大小合适的向量并复制到其中:

vector<int> getConcatenation(const vector<int>& nums) {
    vector<int> result(2 * nums.size());
    std::copy(nums.begin(), nums.end(), result.begin());
    std::copy(nums.begin(), nums.end(), result.begin() + nums.size());
    return result;
}

【讨论】:

  • @RetiredNinja -- 谢谢。固定。
【解决方案2】:

在您的原始程序中,push_back 使迭代器无效,使用这些无效的迭代器可能导致未定义的行为

解决此问题的一种方法是将std::copy_nstd::vector::resize 一起使用,如下所示:

 vector<int> getConcatenation(vector<int>& nums) {
        
       std::vector<int>::size_type old_Size = nums.size();
       nums.resize(2 * old_Size);
       std::copy_n(nums.begin(), old_Size, nums.begin() + old_Size);
        
        return nums; //NO NEED for this return since the function took vector by reference and so the change is already reflected on passed vector     
    }

您还需要为std::copy_n 添加#include &lt;algorithm&gt;

请注意,由于您的函数使用 vector 作为引用,因此无需返回 nums,因为您对 nums 所做的更改已经反映在原始向量上。所以可以使用void作为函数的返回类型,然后去掉return语句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多