【问题标题】:Get last vector element by reference通过引用获取最后一个向量元素
【发布时间】:2015-12-10 14:20:14
【问题描述】:

我有以下代码将向量的一部分附加到另一个向量。

#include <algorithm>    // std::copy
#include <iostream>
#include <vector>
#include <cmath>
#include <assert.h>

using namespace std;

void copyVec(const std::vector<double> in, std::vector<double> &out, int start, unsigned int length) {
    assert(start>=0 && in.size()>=start+length);
    out.reserve(length);
    cout << in.at(9) << endl;
    out.insert(out.end(), &in.at(start), &in.at(start+length));
}

int main(int argc, char ** argv) {
    int start = 0;
    int end = 9;
    int window_size = 10;

    // initialize
    vector<double> vec1 = vector<double>(window_size);
    for (unsigned int i=0;i<window_size;++i) vec1[i] = i;
    vector<double> vec2 = vector<double>(window_size);
    for (unsigned int i=0;i<window_size;++i) vec2[i] = i*10;

    // print
    cout << "vec1: "; 
    for (unsigned int i=0;i<vec1.size();++i) cout << vec1[i] << " "; cout << endl;
    cout << "vec2: "; 
    for (unsigned int i=0;i<vec2.size();++i) cout << vec2[i] << " "; cout << endl;

    copyVec(vec1,vec2,start,end);

    // print
    cout << "vec2: "; for (unsigned int i=0;i<vec2.size();++i) cout << vec2[i] << " "; cout << endl;

    return 0;
}

我似乎无法通过引用访问 vec2 的最后一个元素。 这个例子的输出(int end = 9)是

size: 10 start: 0 end: 9
vec1: 0 1 2 3 4 5 6 7 8 9 
vec2: 0 10 20 30 40 50 60 70 80 90 
in[9]: 9 &in[9]: 0x186d118
vec2: 0 10 20 30 40 50 60 70 80 90 0 1 2 3 4 5 6 7 8

当然,对于 int end = 10,我得到一个超出范围的错误:

size: 10 start: 0 end: 10
vec1: 0 1 2 3 4 5 6 7 8 9 
vec2: 0 10 20 30 40 50 60 70 80 90 
in[9]: 9 &in[9]: 0xae1118
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check
Aborted (core dumped)

那么我应该如何(有效地)附加最后一个向量元素?

【问题讨论】:

  • 为什么不使用push_back()
  • 您是否尝试过使用push_back?另外,您将输入参数作为const std::vector&lt;double&gt; in 传递,为什么不是const std::vector&lt;double&gt;&amp; in?你会避免做不必要的副本。而且,您不是通过引用插入最后一个元素,而是插入最后一个元素的内存位置。
  • out.insert(out.end(), in.begin(), in.end());
  • Logicrat 因为 push_back 对所有元素逐个迭代,所以我需要以尽可能最快的方式处理操作。 @AlgirdasPreidžius 你对裁判的看法是对的,谢谢:)
  • @Ata3ias 而且,您知道它会遍历元素吗?你是怎么测试的?正如here 所述,push_back 的复杂度是恒定的,而不是 O(n),这意味着它不会遍历向量。

标签: c++


【解决方案1】:

您的插入应该直接使用迭代器:

out.insert(out.end(), in.begin() + start, in.begin() + (start + length));

【讨论】:

    【解决方案2】:

    正确的函数如下所示

    #include <iterator>
    #include <vector>
    
    //...
    
    void copyVec( const std::vector<double> &in, 
                  std::vector<double> &out, 
                  std::vector<double>::size_type start, 
                  std::vector<double>::size_type length ) 
    {
        assert( in.size() >= start + length );
    
        out.reserve( out.size() + length );
    
        out.insert( out.end(), std::next( in.begin(), start ), 
                               std::next( in.begin(), start + length ) );
    }
    

    第一个参数被声明为常量引用。考虑到其当前大小,您应该为目标向量保留内存。 最好使用自己的向量迭代器而不是原始指针。 startstart + length 指定一个范围,如 [start, start + length )

    例如复制整个向量你可以写

    copyVec2b(vec1, vec2, 0, vec1.size() );
    

    一般情况下你可能不会在函数中写

    cout << in.at( start + length ) << endl;
    

    因为索引start + length 不包含在复制元素的范围内。

    你可以写

    if ( length != 0 ) cout << in.at( start + length - 1 ) << endl;
    

    【讨论】:

      猜你喜欢
      • 2015-01-11
      • 1970-01-01
      • 2023-01-02
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 2016-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多