需确保i+2 < len(arr),即i最大为len(arr)-3,循环范围为range(len(arr)-2)。

用 for 循环遍历并检查连续三个元素的奇偶性
直接遍历数组,对每个位置 i 检查 arr[i]、arr[i+1]、arr[i+2] 是否都为奇数。关键点是循环上界不能越界:必须保证 i + 2 ,即 <code>i 最大取到 n - 3。
常见错误是写成 i 或 <code>i (当 <code>n == 0 时可能整型溢出),应统一用 i 前先判断 <code>n 直接返回 <code>false。
- 判断奇数用
arr[i] % 2 != 0,注意负数取模在 C++ 中结果符号依赖于被除数,但% 2对所有整数都安全(-3 % 2 == -1,仍非零) - 不要用
arr[i] & 1替代,虽然效率高,但对负数补码下也成立;不过可读性差,且无必要优化 - 一旦找到三个连续奇数,立即
return true,无需继续
使用 std::adjacent_find 配合自定义谓词(C++17 起更简洁)
std::adjacent_find 本用于找两个相邻相同元素,但可通过包装逻辑模拟“三个连续”:先找前两个奇数,再检查第三个。不过原生不支持三元组,所以更实际的做法是写个简单循环,或用 std::search 配合自定义迭代器谓词——但代价高,不推荐。
真正适合的其实是手写一个三元滑动窗口,或封装成辅助函数:
立即学习“C++免费学习笔记(深入)”;
auto hasThreeConsecutiveOdds = [](const std::vector<int>& v) -> bool {
if (v.size() < 3) return false;
for (size_t i = 0; i <= v.size() - 3; ++i) {
if (v[i] % 2 && v[i+1] % 2 && v[i+2] % 2)
return true;
}
return false;
};注意:这里用 v[i] % 2 作为条件等价于 v[i] % 2 != 0,因为非零即真;但显式写 != 0 更清晰,尤其在静态分析或团队规范中。
处理边界情况:空数组、长度不足、全偶数
这些不是“异常”,而是合法输入,必须显式覆盖:
-
std::vector<int>{}→ size 为 0,n 成立,直接返回 <code>false -
{2, 4}或{1, 2}→ 同样跳过循环体 -
{1, 3, 5, 2, 7, 9, 11}→ 第一组就命中,返回true -
{1, 3, 2, 5, 7, 9}→ 第二组[5,7,9]在索引 3 开始,仍能捕获
容易忽略的是:若用有符号整数索引(如 int i),当 v.size() 返回 size_t(无符号),i 在 <code>v.size() 时会因无符号回绕成极大值,导致无限循环或越界访问。务必用 <code>size_t i 或提前判长度。
性能与可读性的实际权衡
这个问题没有隐藏的复杂度,O(n) 时间、O(1) 空间就是最优。不必引入 std::any_of 套嵌套、lambda 捕获或额外容器——只会增加理解成本和潜在 bug。
如果数组来自外部且极长(如百万级),现代 CPU 的分支预测对连续奇数判断很友好,无需手动向量化;但若真要极致优化,可每 4 个元素一组做位运算粗筛(比如把低 1 位提取成掩码再查表),但绝大多数场景纯属过度设计。
最易被忽略的一点:函数接口要不要接受 std::span<const int>(C++20)?如果调用方传的是 C 风格数组或子数组,用 std::span 比 const std::vector& 更通用且零开销;但若项目未启用 C++20,老老实实用 const std::vector& 或迭代器对即可。


















