C++ 等速提取子向量

C++ 等速提取子向量,c++,arrays,vector,stl,time-complexity,C++,Arrays,Vector,Stl,Time Complexity,我有一个std::vector,我想扔掉x-first和y-last元素。仅仅复制元素不是一个选项,因为这是O(n)。 是否有类似于vector.begin()+=x的方法让向量开始得晚,结束得早? 我也试过了 items = std::vector<int> (&items[x+1],&items[0]+items.size()-y); items=std::vector(&items[x+1],&items[0]+items.size()-y); 其中item

我有一个
std::vector
,我想扔掉x-first和y-last元素。仅仅复制元素不是一个选项,因为这是
O(n)
。 是否有类似于
vector.begin()+=x
的方法让向量开始得晚,结束得早? 我也试过了

items = std::vector<int> (&items[x+1],&items[0]+items.size()-y);
items=std::vector(&items[x+1],&items[0]+items.size()-y);

其中items是我的向量,但这给了我
bad\u alloc

如果您只需要一个值范围,那么可以将其表示为从该范围的第一个元素到最后一个元素的一对迭代器。这些可以在恒定的时间内获得

编辑:根据评论中的描述,这似乎是最明智的解决方案。如果您的函数需要一个向量引用,那么您需要重构一点

其他解决办法:

如果不需要原始向量,因此可以对其进行修改,并且元素的顺序不相关,则可以将第一个
x
元素与
n-x-y…n-y
元素交换,然后删除最后一个
x+y
元素。这可以在
O(x+y)
时间内完成

如果合适,您可以选择使用
std::list
,如果子列表的第一个和最后一个节点有迭代器,那么您所要求的可以在固定时间内完成。这还要求您可以修改原始列表,但元素的顺序不会改变


如果这些不是选项,那么您需要复制并使用
O(n)

如果您只需要一个范围的值,那么您可以将其表示为从该范围的第一个到最后一个元素的一对迭代器。这些可以在恒定的时间内获得

编辑:根据评论中的描述,这似乎是最明智的解决方案。如果您的函数需要一个向量引用,那么您需要重构一点

其他解决办法:

如果不需要原始向量,因此可以对其进行修改,并且元素的顺序不相关,则可以将第一个
x
元素与
n-x-y…n-y
元素交换,然后删除最后一个
x+y
元素。这可以在
O(x+y)
时间内完成

如果合适,您可以选择使用
std::list
,如果子列表的第一个和最后一个节点有迭代器,那么您所要求的可以在固定时间内完成。这还要求您可以修改原始列表,但元素的顺序不会改变


如果这些都不是选项,那么您需要复制并坚持使用
O(n)

C++标准算法在范围上工作,而不是在实际的容器上,因此您不需要提取任何内容:您只需要调整正在使用的迭代器范围

void foo(const std::vector<T>& vec, const size_t start, const size_t end)
{
    assert(vec.size() >= end-start);
    auto it1 = vec.begin() + start;
    auto it2 = vec.begin() + end;

    std::whatever(it1, it2);
}
void foo(const std::vector&vec,const size\u t start,const size\u t end)
{
断言(向量大小()>=end-start);
自动it1=vec.begin()+启动;
自动it2=vec.begin()+end;
标准::无论什么(it1、it2);
}
我不明白为什么需要比这更复杂


()C++标准算法在范围上工作,而不是在实际的容器上,因此您不需要提取任何内容:您只需要调整正在使用的迭代器范围

void foo(const std::vector<T>& vec, const size_t start, const size_t end)
{
    assert(vec.size() >= end-start);
    auto it1 = vec.begin() + start;
    auto it2 = vec.begin() + end;

    std::whatever(it1, it2);
}
void foo(const std::vector&vec,const size\u t start,const size\u t end)
{
断言(向量大小()>=end-start);
自动it1=vec.begin()+启动;
自动it2=vec.begin()+end;
标准::无论什么(it1、it2);
}
我不明白为什么需要比这更复杂


其他答案都是正确的:通常迭代器就可以了

不过,您也可以编写向量视图。这是一张草图:

template<typename T>
struct vector_view
{
    vector_view(std::vector<T> const& v, size_t ind_begin, size_t ind_end)
        : _v(v)
        , _size(/* size of range */)
        , _ind_begin(ind_begin) {}

    auto size() const { return _size; }

    auto const& operator[](size_t i) const
    {
        //possibly check for input outside range
        return _v[ i + _ind_begin ];
    }

    //conversion of view to std::vector
    operator std::vector<T>() const
    {
        std::vector<T> ret(_size);
        //fill it
        return ret;
    }

private:
    std::vector<T> const& _v;
    size_t _size;
    size_t _ind_begin;
}
模板
结构向量视图
{
向量视图(标准::向量常量和v、大小索引开始、大小索引结束)
:_v(v)
,_大小(/*范围大小*/)
,_ind_begin(ind_begin){}
自动大小()常量{return\u size;}
自动常数和运算符[](大小i)常数
{
//可能检查输入是否超出范围
返回v[i+\u ind\u begin];
}
//视图到std::vector的转换
运算符std::vector()常量
{
标准::向量ret(_大小);
//填满它
返回ret;
}
私人:
std::向量常数&_v;
大小(t)大小;;
开始时的大小;
}
根据需要公开更多的方法(当您想在标准库算法中使用迭代器时,一些迭代器可能是合适的)

此外,注意常量参考
std::vector const&v--如果这可能是一个问题,那么最好使用共享指针


你也可以在这里想到更一般的方法,例如,使用步幅或类似的东西。

其他答案是正确的:通常迭代器可以

不过,您也可以编写向量视图。这是一张草图:

template<typename T>
struct vector_view
{
    vector_view(std::vector<T> const& v, size_t ind_begin, size_t ind_end)
        : _v(v)
        , _size(/* size of range */)
        , _ind_begin(ind_begin) {}

    auto size() const { return _size; }

    auto const& operator[](size_t i) const
    {
        //possibly check for input outside range
        return _v[ i + _ind_begin ];
    }

    //conversion of view to std::vector
    operator std::vector<T>() const
    {
        std::vector<T> ret(_size);
        //fill it
        return ret;
    }

private:
    std::vector<T> const& _v;
    size_t _size;
    size_t _ind_begin;
}
模板
结构向量视图
{
向量视图(标准::向量常量和v、大小索引开始、大小索引结束)
:_v(v)
,_大小(/*范围大小*/)
,_ind_begin(ind_begin){}
自动大小()常量{return\u size;}
自动常数和运算符[](大小i)常数
{
//可能检查输入是否超出范围
返回v[i+\u ind\u begin];
}
//视图到std::vector的转换
运算符std::vector()常量
{
标准::向量ret(_大小);
//填满它
返回ret;
}
私人:
std::向量常数&_v;
大小(t)大小;;
开始时的大小;
}
根据需要公开更多的方法(当您想在标准库算法中使用迭代器时,一些迭代器可能是合适的)

此外,注意常量参考
std::vector const&v--如果这可能是一个问题,那么最好使用共享指针


你也可以在这里想到更一般的方法,例如,使用跨步或类似的方法。

也许你应该说明你试图这样做的高层次问题是什么