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) 的区间。

posted @ 2026-03-14 10:34  Time_q  阅读(2)  评论(0)    收藏  举报