让我们假设我有以下向量:
std::vector<int> data{0,1,2,3,4};
我想用一个数字替换序列{1,2,3}。我找到了一个带有std :: replace的示例,但是有一个数字被其他单个数字替换。如何替换向量中的序列?
答案 0 :(得分:1)
我们可以使用std::vector::erase(const_iterator first, const_iterator last)
进行以下操作。
以下函数将org[start]
的值替换为val
,然后擦除范围[start+1, end]
中的元素:
template<class T>
std::vector<T> replace(
const std::vector<T>& org,
std::size_t start,
std::size_t end,
const T& val)
{
assert(start <= end);
assert(end < org.size());
auto vec(org);
auto it_s = vec.begin() + start;
*it_s = val;
vec.erase(it_s + 1, vec.begin() + end + 1);
return vec;
}
答案 1 :(得分:1)
我已经通过使用迭代器对而不是向量来将您的问题推广到任何STL容器中。该算法分为3个步骤:
last
由于迭代器无法真正擦除容器中的项目,因此需要进行data.erase(newEnd, data.end());
调用来缩小向量。
算法应该非常稳定,即使对于1元素向量也可以使用。
从C ++ 14开始,函数可以声明为constexpr
。
#include <algorithm>
#include <iostream>
#include <vector>
template <class ForwardIt1, class ForwardIt2, class Value>
constexpr ForwardIt1 replaceSequenceWithValue(ForwardIt1 first, ForwardIt1 last,
ForwardIt2 s_first, ForwardIt2 s_last,
Value &&value) {
auto seq_start = std::search(first, last, s_first, s_last);
if (seq_start == last)
return last; // return last if no seq was found
*seq_start = std::forward<Value>(value);
auto itemsToBeRemoved = std::distance(s_first, s_last) - 1;
// return new end
if (itemsToBeRemoved > 0)
return std::remove_if(std::next(seq_start), last,
[&itemsToBeRemoved](const auto &) { return itemsToBeRemoved-- > 0; });
return last;
}
int main() {
std::vector<int> data{0, 1, 2, 3, 4};
std::vector<int> seq{1, 2, 3};
auto newEnd = replaceSequenceWithValue(data.begin(), data.end(), seq.begin(), seq.end(), 5);
data.erase(newEnd, data.end());
for (auto d : data) {
std::cout << d << '\n';
}
}
如果不需要这种概括,可以将其包装成具有更简单签名的函数:
template <class Value>
constexpr void replaceSequenceWithValue(std::vector<Value> &data, const std::vector<Value> &sequence, Value &&value) {
auto newEnd = replaceSequenceWithValue(data.begin(), data.end(), sequence.begin(),
sequence.end(), std::forward<Value>(value));
data.erase(newEnd, data.end());
}
并像这样使用:
int main() {
std::vector<int> data{0, 1, 2, 3, 4};
replaceSequenceWithValue(data, {1, 2, 3}, 5);
for (auto d : data) {
std::cout << d << '\n';
}
}
答案 2 :(得分:0)
第一: vector::erase
// erasing from vector
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
// set some values (from 1 to 10)
for (int i=1; i<=10; i++) myvector.push_back(i);
// erase the 6th element
myvector.erase (myvector.begin()+5);
// erase the first 3 elements:
myvector.erase (myvector.begin(),myvector.begin()+3);
std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); ++i)
std::cout << ' ' << myvector[i];
std::cout << '\n';
return 0;
}
输出: myvector包含:4 5 7 8 9 10
然后: vector::insert
// inserting into a vector
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector (3,100);
std::vector<int>::iterator it;
it = myvector.begin();
it = myvector.insert ( it , 200 );
myvector.insert (it,2,300);
// "it" no longer valid, get a new one:
it = myvector.begin();
std::vector<int> anothervector (2,400);
myvector.insert (it+2,anothervector.begin(),anothervector.end());
int myarray [] = { 501,502,503 };
myvector.insert (myvector.begin(), myarray, myarray+3);
std::cout << "myvector contains:";
for (it=myvector.begin(); it<myvector.end(); it++)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
输出: myvector包含:501502503300300400400200200100100100
答案 3 :(得分:0)
也许您可以编写一个自定义函数,如下所示:
vector<int> replace_sequence(const vector<int> in,int start,int end,int replace)
{
vector<int> res;
//check the index value
if(start<0 || end > in.size() || start > end){
return res;
}
int distance = end -start;
//construct the result
for(int i=0;i<in.size();i++){
if(i==start){
res.push_back(replace);
i+=distance;
}else{
res.push_back(in[i]);
}
}
return res;
}
答案 4 :(得分:0)
x <- c("1 month ago", "2 years ago", "4 days ago")