You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请教C++代码中嵌套for循环及第三个for循环的实现逻辑

理解这段C++代码中的嵌套循环逻辑

嘿,我来帮你拆解这段代码的逻辑,尤其是你搞不懂的嵌套循环部分~先把代码规整一下方便阅读:

string s; 
cin >> s; 
vector<int> r; 

// 外层的范围for循环
for (string t : {"twone", "one", "two"}) { 
    // 内层的查找循环
    for (size_t pos = 0; (pos = s.find(t, pos)) != string::npos;) { 
        s[pos + t.length() / 2] = '?'; 
        r.push_back(pos + t.length() / 2); 
    } 
} 

cout << r.size() << endl; 
for (auto rr : r) cout << rr + 1 << " "; 
cout << endl;

先搞懂整体功能

这段代码的核心是在输入的字符串里,查找twone、one、two这三个特定子串,记录每个匹配子串的中间位置,同时破坏原串的匹配位置避免重复计数,最后输出找到的子串数量和这些位置(转成从1开始的索引)。


你疑惑的「第三个for循环」:外层范围for循环

你提到的第三个for循环其实是最外层的这个:

for (string t : {"twone", "one", "two"})

这是C++11之后支持的范围for循环,简单说就是依次把花括号里的每个字符串赋值给变量t,循环总共执行3次:

  • 第一次:t的值为"twone"
  • 第二次:t的值为"one"
  • 第三次:t的值为"two"

为啥要按这个顺序?因为twone本质是two+one的组合,如果先找one或two,会把twone拆成两个子串重复计数,先找twone就能避免这个问题。


内层的嵌套for循环:反复查找子串

内层这个循环的写法有点特殊,咱们拆成三部分解析:

for (size_t pos = 0; (pos = s.find(t, pos)) != string::npos;)
  1. 初始化部分:size_t pos = 0 —— 从字符串的第0位(起始位置)开始查找子串。
  2. 条件判断部分:(pos = s.find(t, pos)) != string::npos
    • 先执行s.find(t, pos):从当前pos的位置开始,查找子串t第一次出现的位置。
    • 如果找到,就把这个位置赋值给pos,然后判断pos是否不等于string::npos(npos是C++字符串的特殊值,表示「未找到」),条件成立就进入循环体。
    • 如果没找到,pos会被设为npos,条件不成立,循环结束。
  3. 递增部分:这里是空的!因为每次找到子串后,我们把原串的中间字符改成了?,下次再从当前pos查找时,这个位置的子串已经被破坏,不会重复匹配,所以不需要手动移动pos。

循环体里的操作

进入循环后会执行两个关键操作:

  1. s[pos + t.length() / 2] = '?':计算子串t的中间位置,把原串的这个位置改成?,破坏掉该子串,避免后续重复匹配。比如:
    • twone长度是5,整数除法5/2=2,所以修改pos+2的位置,twone变成tw?ne,再也不会被匹配到。
    • one长度是3,3/2=1,修改pos+1的位置,变成o?e。
  2. r.push_back(pos + t.length() / 2):把这个中间位置(从0开始的索引)存入向量r,后续用来输出结果。

最后的输出逻辑

  • cout << r.size() << endl;:输出找到的子串总数。
  • for (auto rr : r) cout << rr + 1 << " ";:把每个位置从0开始的索引转成从1开始的索引(编程题通常要求用1-based索引),然后依次输出。

内容的提问来源于stack exchange,提问作者McSkelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:28:17