C++使用std::vector迭代器实现末尾回绕到开头的方法求解
解决方案
问题原由
你原有代码存在两个核心错误:
- 直接对迭代器执行
it += k如果超出容器范围属于未定义行为,C++不允许迭代器越过容器的end()边界,哪怕仅做算术运算不访问元素也不符合规范。 it -= items.end()语法不成立:两个迭代器相减得到的是整数类型的偏移量,无法直接赋值给迭代器,且你代码中的items变量未定义。
优雅实现方案
核心思路是用模运算提前计算合法的偏移位置,完全避免迭代器越界,同时天然实现回绕逻辑。
版本1:迭代器实现
#include <vector> int main() { std::vector<int> vec = {1,2,3,4,5}; std::vector<int> vec1; const int k = 3; auto it = vec.begin(); while (!vec.empty()) { size_t current_size = vec.size(); // 计算当前迭代器的下标偏移 size_t current_offset = it - vec.begin(); // 计算回绕后的合法偏移:如果要对齐你给出的示例,将k替换为k-1即可 size_t target_offset = (current_offset + k) % current_size; // 安全移动到目标位置 it = vec.begin() + target_offset; vec1.push_back(*it); // erase返回删除位置的下一个迭代器,作为下次循环的起点 it = vec.erase(it); } }
版本2:下标实现(更简洁)
如果不强制要求用迭代器,直接用下标操作可读性更高,代码更精简:
#include <vector> int main() { std::vector<int> vec = {1,2,3,4,5}; std::vector<int> vec1; const int k = 3; size_t pos = 0; while (!vec.empty()) { // 对齐示例的写法:pos = (pos + k - 1) % vec.size(); pos = (pos + k) % vec.size(); vec1.push_back(vec[pos]); vec.erase(vec.begin() + pos); } }
示例适配说明
你给出的示例中vec{1,2,3,4,5},k=3时第一次取元素3、第二次取元素1,只需要把上述代码中计算偏移的k替换为k-1即可,这是因为示例的逻辑是从当前位置开始数k个元素(包含当前位置),偏移量需要减1。
性能说明
上述实现对于小尺寸vector足够高效,如果你的vector元素量级过万,因为vector::erase删除中间元素的时间复杂度是O(n),整体时间复杂度会达到O(n²),这种场景可以改用循环链表实现,或者直接用约瑟夫环数学公式批量计算结果。
内容的提问来源于stack exchange,提问作者user12326560
相关产品推荐
相关产品推荐

