leet3775
要学习的code
class Solution {
static constexpr string VOWELS = "aeiou";
//这个constexpr就是强调,这个绝对不可以变
template<ranges::input_range R>
/*这个写法,我定义了一个模板,但为了防止你传入乱七八糟的类型
(比如传入一个 int 整数或者一个根本不能遍历的类),
我给参数 R 加了一个硬性条件。”
int count_vowel(const R& s) {
int vowel = 0;
for (char c : s) {
if (VOWELS.find(c) != string::npos) {
vowel++;
}
}
return vowel;
}
public:
string reverseWords(string s) {
int cnt0 = -1;
for (auto t : s | views::split(' ')) {
//这个写法来自Linux的命令,
int cnt = count_vowel(t);
if (cnt0 < 0) {
cnt0 = cnt;
} else if (cnt == cnt0) {
ranges::reverse(t);
}
}
return s;
}
};
关于那个类型Linux命令的写法解释
字符串 s = "heiow woehnf fsosd" 在内存中就是一个连续的字符数组。
views::split 本质上是一个生成器,它并不产生三个 string 对象,而是维护了一个“正在遍历的当前位置”。
2. 它是如何“切分”的?(内部逻辑)
当你执行 for (auto t : s | views::split(' ')) 时,编译器会生成一个迭代器:
第一轮循环 (t 对应 "heiow"):
视图内部有一个变量 current_pos 指向字符串开头 h。
视图开始扫描,直到找到第一个空格 ' '。
它记录下这段区间 [h, w)(起始地址和结束地址)。
t 就是一个 subrange,它包含了指向 h 的指针和指向空格位置的指针。
当你调用 count_vowel(t) 时,函数内部的 for (char c : t) 实际上就是利用 t 内部的两个指针在原字符串的 [0, 5) 区间上进行遍历。完全没有发生内存拷贝!
第二轮循环 (t 对应 "woehnf"):
视图将 current_pos 移动到上一个空格的后面(即 w 的位置)。
继续扫描,直到找到下一个空格。
t 现在指向 [w, f) 的区间。
第三轮循环 (t 对应 "fsosd"):
视图将 current_pos 移动到第二个空格的后面(即 f 的位置)。
扫描到字符串结束(\0)。
t 指向 [f, end) 的区间。

浙公网安备 33010602011771号