c++ - 如何替换向量中的序列
问题描述
假设我有以下向量:
std::vector<int> data{0,1,2,3,4};
我想用一个数字替换序列 {1,2,3}。我找到了一个带有 std::replace 的示例,但是有一个数字被其他单个数字替换。如何替换向量中的序列?
解决方案
通过使用迭代器对而不是向量作为输入,我已将您的问题推广到任何 STL 容器中。该算法有3个步骤:
- 通过std::search查找序列。
last
没找到就返回 - 用新值替换第一个序列项
- 使用std::remove_if删除剩余项目
由于迭代器不能真正从容器中删除项目,data.erase(newEnd, data.end());
因此需要调用来缩小向量。
算法应该非常稳定,甚至适用于 1 元素向量。constexpr
从 C++14 开始可以声明函数。
#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';
}
}
推荐阅读
- html - 具有列数的伪类在 Safari 浏览器中不起作用
- python - ElasticSearch _find 方法来获取保存的对象返回“未找到 URI 的处理程序 [/s/
/api/saved_objects/_find...] 和方法 [GET]" - c# - 如何训练程序使用 PCA C# 识别人脸?
- oracle - 编写 PL/SQL 代码生成从 1 到 500 的 Armstrong 数
- azureservicebus - 如何从不同的进程在 ServiceBus 中完成消息/放弃消息异步?
- vhdl - 如何删除一个额外的时钟周期以在 VHDL 中输出?
- reactjs - 当子组件触发方法时,父组件中的状态不会更新
- php - 按 SKU 和父 ID 对 WooCommerce 购物车进行排序
- angular - 如何屏蔽输入文本框中输入的每三个数字。单击提交按钮时,必须显示原始的未屏蔽值
- c - 带有变量连接问题的字符串