[{"data":1,"prerenderedAt":2452},["ShallowReactive",2],{"page-\u002Fcpp\u002Ffeatures\u002Fstring-和-algorithm":3},{"id":4,"title":5,"body":6,"description":25,"extension":2446,"meta":2447,"navigation":80,"path":2448,"seo":2449,"stem":2450,"__hash__":2451},"content\u002Fcpp\u002Ffeatures\u002Fstring 和 algorithm.md","C++ string 和 algorithm",{"type":7,"value":8,"toc":2387},"minimark",[9,22,26,42,45,52,192,340,346,358,391,402,410,429,441,461,468,501,504,510,529,536,556,559,570,577,597,604,624,631,666,677,685,704,737,744,754,778,791,818,825,871,874,877,881,957,960,1098,1102,1105,1160,1163,1269,1273,1304,1310,1360,1364,1458,1462,1540,1544,1554,1618,1622,1690,1693,1750,1754,1757,1798,1802,1808,1878,1881,1946,1950,1960,2051,2055,2129,2133,2179,2182,2185,2227,2230,2236,2239,2248,2251,2259,2278,2281,2290,2293,2299,2302,2318,2324,2328,2341,2344,2352,2355,2380,2383],[10,11,13,14,18,19],"h1",{"id":12},"c-string-和-algorithm","C++ ",[15,16,17],"code",{},"string"," 和 ",[15,20,21],{},"algorithm",[23,24,25],"p",{},"这两个库几乎是字符串题的默认搭档：",[27,28,29,36],"ul",{},[30,31,32,35],"li",{},[15,33,34],{},"std::string"," 负责存储、切片、查找、替换。",[30,37,38,41],{},[15,39,40],{},"\u003Calgorithm>"," 负责排序、翻转、变换、去重、统计区间操作。",[23,43,44],{},"把它们配合起来，用很少的代码就能把很多字符串题写得很清晰。",[46,47,49,51],"h2",{"id":48},"string-常用操作速查",[15,50,17],{}," 常用操作速查",[53,54,59],"pre",{"className":55,"code":56,"language":57,"meta":58,"style":58},"language-cpp shiki shiki-themes github-light github-dark","#include \u003Cstring>\n#include \u003Ciostream>\n\nint main() {\n    std::string s1 = \"hello\";\n    std::string s2 = \"world\";\n\n    std::string s3 = s1 + \" \" + s2;   \u002F\u002F 拼接: \"hello world\"\n    s1.append(\" C++\");                 \u002F\u002F 追加: \"hello C++\"\n    s1.insert(6, \"modern \");           \u002F\u002F 插入: \"hello modern C++\"\n    s1.replace(6, 6, \"awesome\");       \u002F\u002F 替换: \"hello awesome C++\"\n\n    size_t pos = s1.find(\"awesome\");   \u002F\u002F 查找，返回 6\n    std::string sub = s1.substr(6, 7); \u002F\u002F 子串: \"awesome\"\n\n    char ch = s1[1];                   \u002F\u002F 下标访问: 'e'\n    char front = s1.front();           \u002F\u002F 首字符\n    char back = s1.back();             \u002F\u002F 尾字符\n\n    size_t len = s1.size();            \u002F\u002F 长度\n    bool empty = s1.empty();           \u002F\u002F 是否为空\n}\n","cpp","",[15,60,61,69,75,82,88,94,100,105,111,117,123,129,134,140,146,151,157,163,169,174,180,186],{"__ignoreMap":58},[62,63,66],"span",{"class":64,"line":65},"line",1,[62,67,68],{},"#include \u003Cstring>\n",[62,70,72],{"class":64,"line":71},2,[62,73,74],{},"#include \u003Ciostream>\n",[62,76,78],{"class":64,"line":77},3,[62,79,81],{"emptyLinePlaceholder":80},true,"\n",[62,83,85],{"class":64,"line":84},4,[62,86,87],{},"int main() {\n",[62,89,91],{"class":64,"line":90},5,[62,92,93],{},"    std::string s1 = \"hello\";\n",[62,95,97],{"class":64,"line":96},6,[62,98,99],{},"    std::string s2 = \"world\";\n",[62,101,103],{"class":64,"line":102},7,[62,104,81],{"emptyLinePlaceholder":80},[62,106,108],{"class":64,"line":107},8,[62,109,110],{},"    std::string s3 = s1 + \" \" + s2;   \u002F\u002F 拼接: \"hello world\"\n",[62,112,114],{"class":64,"line":113},9,[62,115,116],{},"    s1.append(\" C++\");                 \u002F\u002F 追加: \"hello C++\"\n",[62,118,120],{"class":64,"line":119},10,[62,121,122],{},"    s1.insert(6, \"modern \");           \u002F\u002F 插入: \"hello modern C++\"\n",[62,124,126],{"class":64,"line":125},11,[62,127,128],{},"    s1.replace(6, 6, \"awesome\");       \u002F\u002F 替换: \"hello awesome C++\"\n",[62,130,132],{"class":64,"line":131},12,[62,133,81],{"emptyLinePlaceholder":80},[62,135,137],{"class":64,"line":136},13,[62,138,139],{},"    size_t pos = s1.find(\"awesome\");   \u002F\u002F 查找，返回 6\n",[62,141,143],{"class":64,"line":142},14,[62,144,145],{},"    std::string sub = s1.substr(6, 7); \u002F\u002F 子串: \"awesome\"\n",[62,147,149],{"class":64,"line":148},15,[62,150,81],{"emptyLinePlaceholder":80},[62,152,154],{"class":64,"line":153},16,[62,155,156],{},"    char ch = s1[1];                   \u002F\u002F 下标访问: 'e'\n",[62,158,160],{"class":64,"line":159},17,[62,161,162],{},"    char front = s1.front();           \u002F\u002F 首字符\n",[62,164,166],{"class":64,"line":165},18,[62,167,168],{},"    char back = s1.back();             \u002F\u002F 尾字符\n",[62,170,172],{"class":64,"line":171},19,[62,173,81],{"emptyLinePlaceholder":80},[62,175,177],{"class":64,"line":176},20,[62,178,179],{},"    size_t len = s1.size();            \u002F\u002F 长度\n",[62,181,183],{"class":64,"line":182},21,[62,184,185],{},"    bool empty = s1.empty();           \u002F\u002F 是否为空\n",[62,187,189],{"class":64,"line":188},22,[62,190,191],{},"}\n",[53,193,195],{"className":55,"code":194,"language":57,"meta":58,"style":58},"\u002F\u002F 容量相关\nsize() \u002F length()    \u002F\u002F 长度\ncapacity()           \u002F\u002F 当前容量\nreserve(n)           \u002F\u002F 预留容量\nresize(n, c)         \u002F\u002F 调整长度，不足时用 c 填充\nshrink_to_fit()      \u002F\u002F 请求回收多余容量\n\n\u002F\u002F 修改相关\npush_back(c)         \u002F\u002F 末尾追加一个字符\npop_back()           \u002F\u002F 删除最后一个字符\nappend(str)          \u002F\u002F 追加字符串\ninsert(pos, str)     \u002F\u002F 插入字符串\nerase(pos, len)      \u002F\u002F 删除子串\nreplace(pos, len, str) \u002F\u002F 替换子串\nclear()              \u002F\u002F 清空\nswap(str)            \u002F\u002F 交换\n\n\u002F\u002F 查找相关\nfind(str, pos)       \u002F\u002F 从左往右找\nrfind(str, pos)      \u002F\u002F 从右往左找\nfind_first_of(str)   \u002F\u002F 找到第一个属于 str 集合的字符\nfind_last_of(str)    \u002F\u002F 找到最后一个属于 str 集合的字符\nfind_first_not_of(str) \u002F\u002F 找到第一个不属于 str 集合的字符\nfind_last_not_of(str)  \u002F\u002F 找到最后一个不属于 str 集合的字符\n\n\u002F\u002F 比较相关\ncompare(str)         \u002F\u002F \u003C0 \u002F ==0 \u002F >0\n== != \u003C > \u003C= >=      \u002F\u002F 直接支持字典序比较\n",[15,196,197,202,207,212,217,222,227,231,236,241,246,251,256,261,266,271,276,280,285,290,295,300,305,311,317,322,328,334],{"__ignoreMap":58},[62,198,199],{"class":64,"line":65},[62,200,201],{},"\u002F\u002F 容量相关\n",[62,203,204],{"class":64,"line":71},[62,205,206],{},"size() \u002F length()    \u002F\u002F 长度\n",[62,208,209],{"class":64,"line":77},[62,210,211],{},"capacity()           \u002F\u002F 当前容量\n",[62,213,214],{"class":64,"line":84},[62,215,216],{},"reserve(n)           \u002F\u002F 预留容量\n",[62,218,219],{"class":64,"line":90},[62,220,221],{},"resize(n, c)         \u002F\u002F 调整长度，不足时用 c 填充\n",[62,223,224],{"class":64,"line":96},[62,225,226],{},"shrink_to_fit()      \u002F\u002F 请求回收多余容量\n",[62,228,229],{"class":64,"line":102},[62,230,81],{"emptyLinePlaceholder":80},[62,232,233],{"class":64,"line":107},[62,234,235],{},"\u002F\u002F 修改相关\n",[62,237,238],{"class":64,"line":113},[62,239,240],{},"push_back(c)         \u002F\u002F 末尾追加一个字符\n",[62,242,243],{"class":64,"line":119},[62,244,245],{},"pop_back()           \u002F\u002F 删除最后一个字符\n",[62,247,248],{"class":64,"line":125},[62,249,250],{},"append(str)          \u002F\u002F 追加字符串\n",[62,252,253],{"class":64,"line":131},[62,254,255],{},"insert(pos, str)     \u002F\u002F 插入字符串\n",[62,257,258],{"class":64,"line":136},[62,259,260],{},"erase(pos, len)      \u002F\u002F 删除子串\n",[62,262,263],{"class":64,"line":142},[62,264,265],{},"replace(pos, len, str) \u002F\u002F 替换子串\n",[62,267,268],{"class":64,"line":148},[62,269,270],{},"clear()              \u002F\u002F 清空\n",[62,272,273],{"class":64,"line":153},[62,274,275],{},"swap(str)            \u002F\u002F 交换\n",[62,277,278],{"class":64,"line":159},[62,279,81],{"emptyLinePlaceholder":80},[62,281,282],{"class":64,"line":165},[62,283,284],{},"\u002F\u002F 查找相关\n",[62,286,287],{"class":64,"line":171},[62,288,289],{},"find(str, pos)       \u002F\u002F 从左往右找\n",[62,291,292],{"class":64,"line":176},[62,293,294],{},"rfind(str, pos)      \u002F\u002F 从右往左找\n",[62,296,297],{"class":64,"line":182},[62,298,299],{},"find_first_of(str)   \u002F\u002F 找到第一个属于 str 集合的字符\n",[62,301,302],{"class":64,"line":188},[62,303,304],{},"find_last_of(str)    \u002F\u002F 找到最后一个属于 str 集合的字符\n",[62,306,308],{"class":64,"line":307},23,[62,309,310],{},"find_first_not_of(str) \u002F\u002F 找到第一个不属于 str 集合的字符\n",[62,312,314],{"class":64,"line":313},24,[62,315,316],{},"find_last_not_of(str)  \u002F\u002F 找到最后一个不属于 str 集合的字符\n",[62,318,320],{"class":64,"line":319},25,[62,321,81],{"emptyLinePlaceholder":80},[62,323,325],{"class":64,"line":324},26,[62,326,327],{},"\u002F\u002F 比较相关\n",[62,329,331],{"class":64,"line":330},27,[62,332,333],{},"compare(str)         \u002F\u002F \u003C0 \u002F ==0 \u002F >0\n",[62,335,337],{"class":64,"line":336},28,[62,338,339],{},"== != \u003C > \u003C= >=      \u002F\u002F 直接支持字典序比较\n",[46,341,343,345],{"id":342},"string-里的几个高频细节",[15,344,17],{}," 里的几个高频细节",[347,348,350,351,354,355],"h3",{"id":349},"_1-find-找不到时返回-npos","1. ",[15,352,353],{},"find"," 找不到时返回 ",[15,356,357],{},"npos",[53,359,361],{"className":55,"code":360,"language":57,"meta":58,"style":58},"std::string s = \"hello\";\nsize_t pos = s.find(\"abc\");\n\nif (pos == std::string::npos) {\n    std::cout \u003C\u003C \"not found\\n\";\n}\n",[15,362,363,368,373,377,382,387],{"__ignoreMap":58},[62,364,365],{"class":64,"line":65},[62,366,367],{},"std::string s = \"hello\";\n",[62,369,370],{"class":64,"line":71},[62,371,372],{},"size_t pos = s.find(\"abc\");\n",[62,374,375],{"class":64,"line":77},[62,376,81],{"emptyLinePlaceholder":80},[62,378,379],{"class":64,"line":84},[62,380,381],{},"if (pos == std::string::npos) {\n",[62,383,384],{"class":64,"line":90},[62,385,386],{},"    std::cout \u003C\u003C \"not found\\n\";\n",[62,388,389],{"class":64,"line":96},[62,390,191],{},[23,392,393,394,397,398,401],{},"不要拿它和 ",[15,395,396],{},"-1"," 直接做语义判断，虽然很多时候结果“看起来能对”，但标准写法应该是 ",[15,399,400],{},"std::string::npos","。",[347,403,405,406,409],{"id":404},"_2-substrpos-len-的第二个参数是长度不是右边界","2. ",[15,407,408],{},"substr(pos, len)"," 的第二个参数是长度，不是右边界",[53,411,413],{"className":55,"code":412,"language":57,"meta":58,"style":58},"std::string s = \"abcdef\";\n\nstd::cout \u003C\u003C s.substr(2, 3) \u003C\u003C '\\n'; \u002F\u002F \"cde\"\n",[15,414,415,420,424],{"__ignoreMap":58},[62,416,417],{"class":64,"line":65},[62,418,419],{},"std::string s = \"abcdef\";\n",[62,421,422],{"class":64,"line":71},[62,423,81],{"emptyLinePlaceholder":80},[62,425,426],{"class":64,"line":77},[62,427,428],{},"std::cout \u003C\u003C s.substr(2, 3) \u003C\u003C '\\n'; \u002F\u002F \"cde\"\n",[347,430,432,433,436,437,440],{"id":431},"_3-operator-不检查越界at-会检查","3. ",[15,434,435],{},"operator[]"," 不检查越界，",[15,438,439],{},"at()"," 会检查",[53,442,444],{"className":55,"code":443,"language":57,"meta":58,"style":58},"std::string s = \"abc\";\nchar x = s[1];     \u002F\u002F 快，但不做边界检查\nchar y = s.at(1);  \u002F\u002F 越界会抛异常\n",[15,445,446,451,456],{"__ignoreMap":58},[62,447,448],{"class":64,"line":65},[62,449,450],{},"std::string s = \"abc\";\n",[62,452,453],{"class":64,"line":71},[62,454,455],{},"char x = s[1];     \u002F\u002F 快，但不做边界检查\n",[62,457,458],{"class":64,"line":77},[62,459,460],{},"char y = s.at(1);  \u002F\u002F 越界会抛异常\n",[347,462,464,465],{"id":463},"_4-频繁拼接长字符串时建议先-reserve","4. 频繁拼接长字符串时，建议先 ",[15,466,467],{},"reserve",[53,469,471],{"className":55,"code":470,"language":57,"meta":58,"style":58},"std::string result;\nresult.reserve(1000);\n\nfor (int i = 0; i \u003C 100; ++i) {\n    result += \"abc\";\n}\n",[15,472,473,478,483,487,492,497],{"__ignoreMap":58},[62,474,475],{"class":64,"line":65},[62,476,477],{},"std::string result;\n",[62,479,480],{"class":64,"line":71},[62,481,482],{},"result.reserve(1000);\n",[62,484,485],{"class":64,"line":77},[62,486,81],{"emptyLinePlaceholder":80},[62,488,489],{"class":64,"line":84},[62,490,491],{},"for (int i = 0; i \u003C 100; ++i) {\n",[62,493,494],{"class":64,"line":90},[62,495,496],{},"    result += \"abc\";\n",[62,498,499],{"class":64,"line":96},[62,500,191],{},[23,502,503],{},"这样可以减少反复扩容带来的开销。",[46,505,507,509],{"id":506},"algorithm-在字符串里的高频招式",[15,508,40],{}," 在字符串里的高频招式",[53,511,513],{"className":55,"code":512,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Ccctype>\n#include \u003Cstring>\n",[15,514,515,520,525],{"__ignoreMap":58},[62,516,517],{"class":64,"line":65},[62,518,519],{},"#include \u003Calgorithm>\n",[62,521,522],{"class":64,"line":71},[62,523,524],{},"#include \u003Ccctype>\n",[62,526,527],{"class":64,"line":77},[62,528,68],{},[347,530,532,533],{"id":531},"_1-排序-sort","1. 排序 ",[15,534,535],{},"sort",[53,537,539],{"className":55,"code":538,"language":57,"meta":58,"style":58},"std::string s = \"dbca\";\nstd::sort(s.begin(), s.end());\n\u002F\u002F s == \"abcd\"\n",[15,540,541,546,551],{"__ignoreMap":58},[62,542,543],{"class":64,"line":65},[62,544,545],{},"std::string s = \"dbca\";\n",[62,547,548],{"class":64,"line":71},[62,549,550],{},"std::sort(s.begin(), s.end());\n",[62,552,553],{"class":64,"line":77},[62,554,555],{},"\u002F\u002F s == \"abcd\"\n",[23,557,558],{},"常用于：",[27,560,561,564,567],{},[30,562,563],{},"判断变位词 \u002F 异位词",[30,565,566],{},"字符去重前的预处理",[30,568,569],{},"把字符串变成规范形态",[347,571,573,574],{"id":572},"_2-翻转-reverse","2. 翻转 ",[15,575,576],{},"reverse",[53,578,580],{"className":55,"code":579,"language":57,"meta":58,"style":58},"std::string s = \"abcde\";\nstd::reverse(s.begin(), s.end());\n\u002F\u002F s == \"edcba\"\n",[15,581,582,587,592],{"__ignoreMap":58},[62,583,584],{"class":64,"line":65},[62,585,586],{},"std::string s = \"abcde\";\n",[62,588,589],{"class":64,"line":71},[62,590,591],{},"std::reverse(s.begin(), s.end());\n",[62,593,594],{"class":64,"line":77},[62,595,596],{},"\u002F\u002F s == \"edcba\"\n",[347,598,600,601],{"id":599},"_3-计数-count","3. 计数 ",[15,602,603],{},"count",[53,605,607],{"className":55,"code":606,"language":57,"meta":58,"style":58},"std::string s = \"banana\";\nint n = std::count(s.begin(), s.end(), 'a');\n\u002F\u002F n == 3\n",[15,608,609,614,619],{"__ignoreMap":58},[62,610,611],{"class":64,"line":65},[62,612,613],{},"std::string s = \"banana\";\n",[62,615,616],{"class":64,"line":71},[62,617,618],{},"int n = std::count(s.begin(), s.end(), 'a');\n",[62,620,621],{"class":64,"line":77},[62,622,623],{},"\u002F\u002F n == 3\n",[347,625,627,628],{"id":626},"_4-批量变换-transform","4. 批量变换 ",[15,629,630],{},"transform",[53,632,634],{"className":55,"code":633,"language":57,"meta":58,"style":58},"std::string s = \"AbC\";\nstd::transform(s.begin(), s.end(), s.begin(),\n    [](unsigned char ch) {\n        return static_cast\u003Cchar>(std::tolower(ch));\n    });\n\u002F\u002F s == \"abc\"\n",[15,635,636,641,646,651,656,661],{"__ignoreMap":58},[62,637,638],{"class":64,"line":65},[62,639,640],{},"std::string s = \"AbC\";\n",[62,642,643],{"class":64,"line":71},[62,644,645],{},"std::transform(s.begin(), s.end(), s.begin(),\n",[62,647,648],{"class":64,"line":77},[62,649,650],{},"    [](unsigned char ch) {\n",[62,652,653],{"class":64,"line":84},[62,654,655],{},"        return static_cast\u003Cchar>(std::tolower(ch));\n",[62,657,658],{"class":64,"line":90},[62,659,660],{},"    });\n",[62,662,663],{"class":64,"line":96},[62,664,665],{},"\u002F\u002F s == \"abc\"\n",[347,667,669,670,673,674],{"id":668},"_5-删除类操作-remove-remove_if","5. 删除类操作 ",[15,671,672],{},"remove"," \u002F ",[15,675,676],{},"remove_if",[23,678,679,681,682,401],{},[15,680,672],{}," 不会真的删元素，它只是把“保留的元素”挪到前面，真正删除要配合 ",[15,683,684],{},"erase",[53,686,688],{"className":55,"code":687,"language":57,"meta":58,"style":58},"std::string s = \"a b  c\";\ns.erase(std::remove(s.begin(), s.end(), ' '), s.end());\n\u002F\u002F s == \"abc\"\n",[15,689,690,695,700],{"__ignoreMap":58},[62,691,692],{"class":64,"line":65},[62,693,694],{},"std::string s = \"a b  c\";\n",[62,696,697],{"class":64,"line":71},[62,698,699],{},"s.erase(std::remove(s.begin(), s.end(), ' '), s.end());\n",[62,701,702],{"class":64,"line":77},[62,703,665],{},[53,705,707],{"className":55,"code":706,"language":57,"meta":58,"style":58},"std::string s = \"a1b2c3\";\ns.erase(std::remove_if(s.begin(), s.end(),\n    [](unsigned char ch) {\n        return std::isdigit(ch);\n    }), s.end());\n\u002F\u002F s == \"abc\"\n",[15,708,709,714,719,723,728,733],{"__ignoreMap":58},[62,710,711],{"class":64,"line":65},[62,712,713],{},"std::string s = \"a1b2c3\";\n",[62,715,716],{"class":64,"line":71},[62,717,718],{},"s.erase(std::remove_if(s.begin(), s.end(),\n",[62,720,721],{"class":64,"line":77},[62,722,650],{},[62,724,725],{"class":64,"line":84},[62,726,727],{},"        return std::isdigit(ch);\n",[62,729,730],{"class":64,"line":90},[62,731,732],{},"    }), s.end());\n",[62,734,735],{"class":64,"line":96},[62,736,665],{},[347,738,740,741],{"id":739},"_6-去重-unique","6. 去重 ",[15,742,743],{},"unique",[23,745,746,748,749,753],{},[15,747,743],{}," 只能去掉",[750,751,752],"strong",{},"相邻重复元素","，所以很多时候要先排序。",[53,755,757],{"className":55,"code":756,"language":57,"meta":58,"style":58},"std::string s = \"cbbaac\";\nstd::sort(s.begin(), s.end()); \u002F\u002F \"aabbcc\"\ns.erase(std::unique(s.begin(), s.end()), s.end());\n\u002F\u002F s == \"abc\"\n",[15,758,759,764,769,774],{"__ignoreMap":58},[62,760,761],{"class":64,"line":65},[62,762,763],{},"std::string s = \"cbbaac\";\n",[62,765,766],{"class":64,"line":71},[62,767,768],{},"std::sort(s.begin(), s.end()); \u002F\u002F \"aabbcc\"\n",[62,770,771],{"class":64,"line":77},[62,772,773],{},"s.erase(std::unique(s.begin(), s.end()), s.end());\n",[62,775,776],{"class":64,"line":84},[62,777,665],{},[347,779,781,782,673,785,673,788],{"id":780},"_7-条件判断-all_of-any_of-none_of","7. 条件判断 ",[15,783,784],{},"all_of",[15,786,787],{},"any_of",[15,789,790],{},"none_of",[53,792,794],{"className":55,"code":793,"language":57,"meta":58,"style":58},"std::string s = \"12345\";\nbool allDigit = std::all_of(s.begin(), s.end(),\n    [](unsigned char ch) {\n        return std::isdigit(ch);\n    });\n",[15,795,796,801,806,810,814],{"__ignoreMap":58},[62,797,798],{"class":64,"line":65},[62,799,800],{},"std::string s = \"12345\";\n",[62,802,803],{"class":64,"line":71},[62,804,805],{},"bool allDigit = std::all_of(s.begin(), s.end(),\n",[62,807,808],{"class":64,"line":77},[62,809,650],{},[62,811,812],{"class":64,"line":84},[62,813,727],{},[62,815,816],{"class":64,"line":90},[62,817,660],{},[347,819,821,822],{"id":820},"_8-查找满足条件的字符-find_if","8. 查找满足条件的字符 ",[15,823,824],{},"find_if",[53,826,828],{"className":55,"code":827,"language":57,"meta":58,"style":58},"std::string s = \"   hello\";\nauto it = std::find_if(s.begin(), s.end(),\n    [](unsigned char ch) {\n        return !std::isspace(ch);\n    });\n\nif (it != s.end()) {\n    std::cout \u003C\u003C *it \u003C\u003C '\\n'; \u002F\u002F 'h'\n}\n",[15,829,830,835,840,844,849,853,857,862,867],{"__ignoreMap":58},[62,831,832],{"class":64,"line":65},[62,833,834],{},"std::string s = \"   hello\";\n",[62,836,837],{"class":64,"line":71},[62,838,839],{},"auto it = std::find_if(s.begin(), s.end(),\n",[62,841,842],{"class":64,"line":77},[62,843,650],{},[62,845,846],{"class":64,"line":84},[62,847,848],{},"        return !std::isspace(ch);\n",[62,850,851],{"class":64,"line":90},[62,852,660],{},[62,854,855],{"class":64,"line":96},[62,856,81],{"emptyLinePlaceholder":80},[62,858,859],{"class":64,"line":102},[62,860,861],{},"if (it != s.end()) {\n",[62,863,864],{"class":64,"line":107},[62,865,866],{},"    std::cout \u003C\u003C *it \u003C\u003C '\\n'; \u002F\u002F 'h'\n",[62,868,869],{"class":64,"line":113},[62,870,191],{},[46,872,873],{"id":873},"常见用例",[23,875,876],{},"下面这些基本就是刷题和日常代码里最常见的套路。",[347,878,880],{"id":879},"_1-判断回文串","1. 判断回文串",[53,882,884],{"className":55,"code":883,"language":57,"meta":58,"style":58},"#include \u003Cstring>\n\nbool isPalindrome(const std::string& s) {\n    int left = 0;\n    int right = static_cast\u003Cint>(s.size()) - 1;\n\n    while (left \u003C right) {\n        if (s[left] != s[right]) {\n            return false;\n        }\n        ++left;\n        --right;\n    }\n    return true;\n}\n",[15,885,886,890,894,899,904,909,913,918,923,928,933,938,943,948,953],{"__ignoreMap":58},[62,887,888],{"class":64,"line":65},[62,889,68],{},[62,891,892],{"class":64,"line":71},[62,893,81],{"emptyLinePlaceholder":80},[62,895,896],{"class":64,"line":77},[62,897,898],{},"bool isPalindrome(const std::string& s) {\n",[62,900,901],{"class":64,"line":84},[62,902,903],{},"    int left = 0;\n",[62,905,906],{"class":64,"line":90},[62,907,908],{},"    int right = static_cast\u003Cint>(s.size()) - 1;\n",[62,910,911],{"class":64,"line":96},[62,912,81],{"emptyLinePlaceholder":80},[62,914,915],{"class":64,"line":102},[62,916,917],{},"    while (left \u003C right) {\n",[62,919,920],{"class":64,"line":107},[62,921,922],{},"        if (s[left] != s[right]) {\n",[62,924,925],{"class":64,"line":113},[62,926,927],{},"            return false;\n",[62,929,930],{"class":64,"line":119},[62,931,932],{},"        }\n",[62,934,935],{"class":64,"line":125},[62,936,937],{},"        ++left;\n",[62,939,940],{"class":64,"line":131},[62,941,942],{},"        --right;\n",[62,944,945],{"class":64,"line":136},[62,946,947],{},"    }\n",[62,949,950],{"class":64,"line":142},[62,951,952],{},"    return true;\n",[62,954,955],{"class":64,"line":148},[62,956,191],{},[23,958,959],{},"如果题目要求“忽略大小写和非字母数字字符”，可以这样写：",[53,961,963],{"className":55,"code":962,"language":57,"meta":58,"style":58},"#include \u003Ccctype>\n#include \u003Cstring>\n\nbool isPalindromeIgnore(const std::string& s) {\n    int left = 0;\n    int right = static_cast\u003Cint>(s.size()) - 1;\n\n    while (left \u003C right) {\n        while (left \u003C right &&\n               !std::isalnum(static_cast\u003Cunsigned char>(s[left]))) {\n            ++left;\n        }\n        while (left \u003C right &&\n               !std::isalnum(static_cast\u003Cunsigned char>(s[right]))) {\n            --right;\n        }\n\n        char lc = static_cast\u003Cchar>(\n            std::tolower(static_cast\u003Cunsigned char>(s[left])));\n        char rc = static_cast\u003Cchar>(\n            std::tolower(static_cast\u003Cunsigned char>(s[right])));\n\n        if (lc != rc) {\n            return false;\n        }\n        ++left;\n        --right;\n    }\n    return true;\n}\n",[15,964,965,969,973,977,982,986,990,994,998,1003,1008,1013,1017,1021,1026,1031,1035,1039,1044,1049,1054,1059,1063,1068,1072,1076,1080,1084,1088,1093],{"__ignoreMap":58},[62,966,967],{"class":64,"line":65},[62,968,524],{},[62,970,971],{"class":64,"line":71},[62,972,68],{},[62,974,975],{"class":64,"line":77},[62,976,81],{"emptyLinePlaceholder":80},[62,978,979],{"class":64,"line":84},[62,980,981],{},"bool isPalindromeIgnore(const std::string& s) {\n",[62,983,984],{"class":64,"line":90},[62,985,903],{},[62,987,988],{"class":64,"line":96},[62,989,908],{},[62,991,992],{"class":64,"line":102},[62,993,81],{"emptyLinePlaceholder":80},[62,995,996],{"class":64,"line":107},[62,997,917],{},[62,999,1000],{"class":64,"line":113},[62,1001,1002],{},"        while (left \u003C right &&\n",[62,1004,1005],{"class":64,"line":119},[62,1006,1007],{},"               !std::isalnum(static_cast\u003Cunsigned char>(s[left]))) {\n",[62,1009,1010],{"class":64,"line":125},[62,1011,1012],{},"            ++left;\n",[62,1014,1015],{"class":64,"line":131},[62,1016,932],{},[62,1018,1019],{"class":64,"line":136},[62,1020,1002],{},[62,1022,1023],{"class":64,"line":142},[62,1024,1025],{},"               !std::isalnum(static_cast\u003Cunsigned char>(s[right]))) {\n",[62,1027,1028],{"class":64,"line":148},[62,1029,1030],{},"            --right;\n",[62,1032,1033],{"class":64,"line":153},[62,1034,932],{},[62,1036,1037],{"class":64,"line":159},[62,1038,81],{"emptyLinePlaceholder":80},[62,1040,1041],{"class":64,"line":165},[62,1042,1043],{},"        char lc = static_cast\u003Cchar>(\n",[62,1045,1046],{"class":64,"line":171},[62,1047,1048],{},"            std::tolower(static_cast\u003Cunsigned char>(s[left])));\n",[62,1050,1051],{"class":64,"line":176},[62,1052,1053],{},"        char rc = static_cast\u003Cchar>(\n",[62,1055,1056],{"class":64,"line":182},[62,1057,1058],{},"            std::tolower(static_cast\u003Cunsigned char>(s[right])));\n",[62,1060,1061],{"class":64,"line":188},[62,1062,81],{"emptyLinePlaceholder":80},[62,1064,1065],{"class":64,"line":307},[62,1066,1067],{},"        if (lc != rc) {\n",[62,1069,1070],{"class":64,"line":313},[62,1071,927],{},[62,1073,1074],{"class":64,"line":319},[62,1075,932],{},[62,1077,1078],{"class":64,"line":324},[62,1079,937],{},[62,1081,1082],{"class":64,"line":330},[62,1083,942],{},[62,1085,1086],{"class":64,"line":336},[62,1087,947],{},[62,1089,1091],{"class":64,"line":1090},29,[62,1092,952],{},[62,1094,1096],{"class":64,"line":1095},30,[62,1097,191],{},[347,1099,1101],{"id":1100},"_2-判断两个字符串是否为异位词","2. 判断两个字符串是否为异位词",[23,1103,1104],{},"方法一：排序，代码最短。",[53,1106,1108],{"className":55,"code":1107,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Cstring>\n\nbool isAnagram(std::string a, std::string b) {\n    if (a.size() != b.size()) {\n        return false;\n    }\n    std::sort(a.begin(), a.end());\n    std::sort(b.begin(), b.end());\n    return a == b;\n}\n",[15,1109,1110,1114,1118,1122,1127,1132,1137,1141,1146,1151,1156],{"__ignoreMap":58},[62,1111,1112],{"class":64,"line":65},[62,1113,519],{},[62,1115,1116],{"class":64,"line":71},[62,1117,68],{},[62,1119,1120],{"class":64,"line":77},[62,1121,81],{"emptyLinePlaceholder":80},[62,1123,1124],{"class":64,"line":84},[62,1125,1126],{},"bool isAnagram(std::string a, std::string b) {\n",[62,1128,1129],{"class":64,"line":90},[62,1130,1131],{},"    if (a.size() != b.size()) {\n",[62,1133,1134],{"class":64,"line":96},[62,1135,1136],{},"        return false;\n",[62,1138,1139],{"class":64,"line":102},[62,1140,947],{},[62,1142,1143],{"class":64,"line":107},[62,1144,1145],{},"    std::sort(a.begin(), a.end());\n",[62,1147,1148],{"class":64,"line":113},[62,1149,1150],{},"    std::sort(b.begin(), b.end());\n",[62,1152,1153],{"class":64,"line":119},[62,1154,1155],{},"    return a == b;\n",[62,1157,1158],{"class":64,"line":125},[62,1159,191],{},[23,1161,1162],{},"方法二：计数，时间复杂度更好，适合只含小写字母的题。",[53,1164,1166],{"className":55,"code":1165,"language":57,"meta":58,"style":58},"#include \u003Carray>\n#include \u003Cstring>\n\nbool isAnagram2(const std::string& a, const std::string& b) {\n    if (a.size() != b.size()) {\n        return false;\n    }\n\n    std::array\u003Cint, 26> cnt{};\n    for (char ch : a) {\n        ++cnt[ch - 'a'];\n    }\n    for (char ch : b) {\n        --cnt[ch - 'a'];\n    }\n\n    for (int x : cnt) {\n        if (x != 0) {\n            return false;\n        }\n    }\n    return true;\n}\n",[15,1167,1168,1173,1177,1181,1186,1190,1194,1198,1202,1207,1212,1217,1221,1226,1231,1235,1239,1244,1249,1253,1257,1261,1265],{"__ignoreMap":58},[62,1169,1170],{"class":64,"line":65},[62,1171,1172],{},"#include \u003Carray>\n",[62,1174,1175],{"class":64,"line":71},[62,1176,68],{},[62,1178,1179],{"class":64,"line":77},[62,1180,81],{"emptyLinePlaceholder":80},[62,1182,1183],{"class":64,"line":84},[62,1184,1185],{},"bool isAnagram2(const std::string& a, const std::string& b) {\n",[62,1187,1188],{"class":64,"line":90},[62,1189,1131],{},[62,1191,1192],{"class":64,"line":96},[62,1193,1136],{},[62,1195,1196],{"class":64,"line":102},[62,1197,947],{},[62,1199,1200],{"class":64,"line":107},[62,1201,81],{"emptyLinePlaceholder":80},[62,1203,1204],{"class":64,"line":113},[62,1205,1206],{},"    std::array\u003Cint, 26> cnt{};\n",[62,1208,1209],{"class":64,"line":119},[62,1210,1211],{},"    for (char ch : a) {\n",[62,1213,1214],{"class":64,"line":125},[62,1215,1216],{},"        ++cnt[ch - 'a'];\n",[62,1218,1219],{"class":64,"line":131},[62,1220,947],{},[62,1222,1223],{"class":64,"line":136},[62,1224,1225],{},"    for (char ch : b) {\n",[62,1227,1228],{"class":64,"line":142},[62,1229,1230],{},"        --cnt[ch - 'a'];\n",[62,1232,1233],{"class":64,"line":148},[62,1234,947],{},[62,1236,1237],{"class":64,"line":153},[62,1238,81],{"emptyLinePlaceholder":80},[62,1240,1241],{"class":64,"line":159},[62,1242,1243],{},"    for (int x : cnt) {\n",[62,1245,1246],{"class":64,"line":165},[62,1247,1248],{},"        if (x != 0) {\n",[62,1250,1251],{"class":64,"line":171},[62,1252,927],{},[62,1254,1255],{"class":64,"line":176},[62,1256,932],{},[62,1258,1259],{"class":64,"line":182},[62,1260,947],{},[62,1262,1263],{"class":64,"line":188},[62,1264,952],{},[62,1266,1267],{"class":64,"line":307},[62,1268,191],{},[347,1270,1272],{"id":1271},"_3-删除字符串中的所有空格","3. 删除字符串中的所有空格",[53,1274,1276],{"className":55,"code":1275,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Cstring>\n\nvoid removeSpaces(std::string& s) {\n    s.erase(std::remove(s.begin(), s.end(), ' '), s.end());\n}\n",[15,1277,1278,1282,1286,1290,1295,1300],{"__ignoreMap":58},[62,1279,1280],{"class":64,"line":65},[62,1281,519],{},[62,1283,1284],{"class":64,"line":71},[62,1285,68],{},[62,1287,1288],{"class":64,"line":77},[62,1289,81],{"emptyLinePlaceholder":80},[62,1291,1292],{"class":64,"line":84},[62,1293,1294],{},"void removeSpaces(std::string& s) {\n",[62,1296,1297],{"class":64,"line":90},[62,1298,1299],{},"    s.erase(std::remove(s.begin(), s.end(), ' '), s.end());\n",[62,1301,1302],{"class":64,"line":96},[62,1303,191],{},[23,1305,1306,1307,1309],{},"如果要删除所有空白字符，包括空格、换行、制表符，用 ",[15,1308,676],{},"：",[53,1311,1313],{"className":55,"code":1312,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Ccctype>\n#include \u003Cstring>\n\nvoid removeAllWhitespace(std::string& s) {\n    s.erase(std::remove_if(s.begin(), s.end(),\n        [](unsigned char ch) {\n            return std::isspace(ch);\n        }), s.end());\n}\n",[15,1314,1315,1319,1323,1327,1331,1336,1341,1346,1351,1356],{"__ignoreMap":58},[62,1316,1317],{"class":64,"line":65},[62,1318,519],{},[62,1320,1321],{"class":64,"line":71},[62,1322,524],{},[62,1324,1325],{"class":64,"line":77},[62,1326,68],{},[62,1328,1329],{"class":64,"line":84},[62,1330,81],{"emptyLinePlaceholder":80},[62,1332,1333],{"class":64,"line":90},[62,1334,1335],{},"void removeAllWhitespace(std::string& s) {\n",[62,1337,1338],{"class":64,"line":96},[62,1339,1340],{},"    s.erase(std::remove_if(s.begin(), s.end(),\n",[62,1342,1343],{"class":64,"line":102},[62,1344,1345],{},"        [](unsigned char ch) {\n",[62,1347,1348],{"class":64,"line":107},[62,1349,1350],{},"            return std::isspace(ch);\n",[62,1352,1353],{"class":64,"line":113},[62,1354,1355],{},"        }), s.end());\n",[62,1357,1358],{"class":64,"line":119},[62,1359,191],{},[347,1361,1363],{"id":1362},"_4-去掉首尾空白","4. 去掉首尾空白",[53,1365,1367],{"className":55,"code":1366,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Ccctype>\n#include \u003Cstring>\n\nstd::string trim(std::string s) {\n    auto left = std::find_if(s.begin(), s.end(),\n        [](unsigned char ch) {\n            return !std::isspace(ch);\n        });\n\n    auto right = std::find_if(s.rbegin(), s.rend(),\n        [](unsigned char ch) {\n            return !std::isspace(ch);\n        }).base();\n\n    if (left >= right) {\n        return \"\";\n    }\n    return std::string(left, right);\n}\n",[15,1368,1369,1373,1377,1381,1385,1390,1395,1399,1404,1409,1413,1418,1422,1426,1431,1435,1440,1445,1449,1454],{"__ignoreMap":58},[62,1370,1371],{"class":64,"line":65},[62,1372,519],{},[62,1374,1375],{"class":64,"line":71},[62,1376,524],{},[62,1378,1379],{"class":64,"line":77},[62,1380,68],{},[62,1382,1383],{"class":64,"line":84},[62,1384,81],{"emptyLinePlaceholder":80},[62,1386,1387],{"class":64,"line":90},[62,1388,1389],{},"std::string trim(std::string s) {\n",[62,1391,1392],{"class":64,"line":96},[62,1393,1394],{},"    auto left = std::find_if(s.begin(), s.end(),\n",[62,1396,1397],{"class":64,"line":102},[62,1398,1345],{},[62,1400,1401],{"class":64,"line":107},[62,1402,1403],{},"            return !std::isspace(ch);\n",[62,1405,1406],{"class":64,"line":113},[62,1407,1408],{},"        });\n",[62,1410,1411],{"class":64,"line":119},[62,1412,81],{"emptyLinePlaceholder":80},[62,1414,1415],{"class":64,"line":125},[62,1416,1417],{},"    auto right = std::find_if(s.rbegin(), s.rend(),\n",[62,1419,1420],{"class":64,"line":131},[62,1421,1345],{},[62,1423,1424],{"class":64,"line":136},[62,1425,1403],{},[62,1427,1428],{"class":64,"line":142},[62,1429,1430],{},"        }).base();\n",[62,1432,1433],{"class":64,"line":148},[62,1434,81],{"emptyLinePlaceholder":80},[62,1436,1437],{"class":64,"line":153},[62,1438,1439],{},"    if (left >= right) {\n",[62,1441,1442],{"class":64,"line":159},[62,1443,1444],{},"        return \"\";\n",[62,1446,1447],{"class":64,"line":165},[62,1448,947],{},[62,1450,1451],{"class":64,"line":171},[62,1452,1453],{},"    return std::string(left, right);\n",[62,1455,1456],{"class":64,"line":176},[62,1457,191],{},[347,1459,1461],{"id":1460},"_5-全部转小写-大写","5. 全部转小写 \u002F 大写",[53,1463,1465],{"className":55,"code":1464,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Ccctype>\n#include \u003Cstring>\n\nvoid toLower(std::string& s) {\n    std::transform(s.begin(), s.end(), s.begin(),\n        [](unsigned char ch) {\n            return static_cast\u003Cchar>(std::tolower(ch));\n        });\n}\n\nvoid toUpper(std::string& s) {\n    std::transform(s.begin(), s.end(), s.begin(),\n        [](unsigned char ch) {\n            return static_cast\u003Cchar>(std::toupper(ch));\n        });\n}\n",[15,1466,1467,1471,1475,1479,1483,1488,1493,1497,1502,1506,1510,1514,1519,1523,1527,1532,1536],{"__ignoreMap":58},[62,1468,1469],{"class":64,"line":65},[62,1470,519],{},[62,1472,1473],{"class":64,"line":71},[62,1474,524],{},[62,1476,1477],{"class":64,"line":77},[62,1478,68],{},[62,1480,1481],{"class":64,"line":84},[62,1482,81],{"emptyLinePlaceholder":80},[62,1484,1485],{"class":64,"line":90},[62,1486,1487],{},"void toLower(std::string& s) {\n",[62,1489,1490],{"class":64,"line":96},[62,1491,1492],{},"    std::transform(s.begin(), s.end(), s.begin(),\n",[62,1494,1495],{"class":64,"line":102},[62,1496,1345],{},[62,1498,1499],{"class":64,"line":107},[62,1500,1501],{},"            return static_cast\u003Cchar>(std::tolower(ch));\n",[62,1503,1504],{"class":64,"line":113},[62,1505,1408],{},[62,1507,1508],{"class":64,"line":119},[62,1509,191],{},[62,1511,1512],{"class":64,"line":125},[62,1513,81],{"emptyLinePlaceholder":80},[62,1515,1516],{"class":64,"line":131},[62,1517,1518],{},"void toUpper(std::string& s) {\n",[62,1520,1521],{"class":64,"line":136},[62,1522,1492],{},[62,1524,1525],{"class":64,"line":142},[62,1526,1345],{},[62,1528,1529],{"class":64,"line":148},[62,1530,1531],{},"            return static_cast\u003Cchar>(std::toupper(ch));\n",[62,1533,1534],{"class":64,"line":153},[62,1535,1408],{},[62,1537,1538],{"class":64,"line":159},[62,1539,191],{},[347,1541,1543],{"id":1542},"_6-替换所有子串","6. 替换所有子串",[23,1545,1546,1547,1550,1551,1309],{},"比如把所有 ",[15,1548,1549],{},"\"ab\""," 替换成 ",[15,1552,1553],{},"\"XY\"",[53,1555,1557],{"className":55,"code":1556,"language":57,"meta":58,"style":58},"#include \u003Cstring>\n\nvoid replaceAll(std::string& s, const std::string& from, const std::string& to) {\n    if (from.empty()) {\n        return;\n    }\n\n    size_t pos = 0;\n    while ((pos = s.find(from, pos)) != std::string::npos) {\n        s.replace(pos, from.size(), to);\n        pos += to.size();\n    }\n}\n",[15,1558,1559,1563,1567,1572,1577,1582,1586,1590,1595,1600,1605,1610,1614],{"__ignoreMap":58},[62,1560,1561],{"class":64,"line":65},[62,1562,68],{},[62,1564,1565],{"class":64,"line":71},[62,1566,81],{"emptyLinePlaceholder":80},[62,1568,1569],{"class":64,"line":77},[62,1570,1571],{},"void replaceAll(std::string& s, const std::string& from, const std::string& to) {\n",[62,1573,1574],{"class":64,"line":84},[62,1575,1576],{},"    if (from.empty()) {\n",[62,1578,1579],{"class":64,"line":90},[62,1580,1581],{},"        return;\n",[62,1583,1584],{"class":64,"line":96},[62,1585,947],{},[62,1587,1588],{"class":64,"line":102},[62,1589,81],{"emptyLinePlaceholder":80},[62,1591,1592],{"class":64,"line":107},[62,1593,1594],{},"    size_t pos = 0;\n",[62,1596,1597],{"class":64,"line":113},[62,1598,1599],{},"    while ((pos = s.find(from, pos)) != std::string::npos) {\n",[62,1601,1602],{"class":64,"line":119},[62,1603,1604],{},"        s.replace(pos, from.size(), to);\n",[62,1606,1607],{"class":64,"line":125},[62,1608,1609],{},"        pos += to.size();\n",[62,1611,1612],{"class":64,"line":131},[62,1613,947],{},[62,1615,1616],{"class":64,"line":136},[62,1617,191],{},[347,1619,1621],{"id":1620},"_7-统计每个字符出现次数","7. 统计每个字符出现次数",[53,1623,1625],{"className":55,"code":1624,"language":57,"meta":58,"style":58},"#include \u003Ciostream>\n#include \u003Cstring>\n#include \u003Cunordered_map>\n\nvoid countChars(const std::string& s) {\n    std::unordered_map\u003Cchar, int> freq;\n    for (char ch : s) {\n        ++freq[ch];\n    }\n\n    for (const auto& [ch, cnt] : freq) {\n        std::cout \u003C\u003C ch \u003C\u003C \": \" \u003C\u003C cnt \u003C\u003C '\\n';\n    }\n}\n",[15,1626,1627,1631,1635,1640,1644,1649,1654,1659,1664,1668,1672,1677,1682,1686],{"__ignoreMap":58},[62,1628,1629],{"class":64,"line":65},[62,1630,74],{},[62,1632,1633],{"class":64,"line":71},[62,1634,68],{},[62,1636,1637],{"class":64,"line":77},[62,1638,1639],{},"#include \u003Cunordered_map>\n",[62,1641,1642],{"class":64,"line":84},[62,1643,81],{"emptyLinePlaceholder":80},[62,1645,1646],{"class":64,"line":90},[62,1647,1648],{},"void countChars(const std::string& s) {\n",[62,1650,1651],{"class":64,"line":96},[62,1652,1653],{},"    std::unordered_map\u003Cchar, int> freq;\n",[62,1655,1656],{"class":64,"line":102},[62,1657,1658],{},"    for (char ch : s) {\n",[62,1660,1661],{"class":64,"line":107},[62,1662,1663],{},"        ++freq[ch];\n",[62,1665,1666],{"class":64,"line":113},[62,1667,947],{},[62,1669,1670],{"class":64,"line":119},[62,1671,81],{"emptyLinePlaceholder":80},[62,1673,1674],{"class":64,"line":125},[62,1675,1676],{},"    for (const auto& [ch, cnt] : freq) {\n",[62,1678,1679],{"class":64,"line":131},[62,1680,1681],{},"        std::cout \u003C\u003C ch \u003C\u003C \": \" \u003C\u003C cnt \u003C\u003C '\\n';\n",[62,1683,1684],{"class":64,"line":136},[62,1685,947],{},[62,1687,1688],{"class":64,"line":142},[62,1689,191],{},[23,1691,1692],{},"如果字符集固定，比如只统计小写字母，用数组更快。",[53,1694,1696],{"className":55,"code":1695,"language":57,"meta":58,"style":58},"#include \u003Carray>\n#include \u003Cstring>\n\nstd::array\u003Cint, 26> countLowerLetters(const std::string& s) {\n    std::array\u003Cint, 26> cnt{};\n    for (char ch : s) {\n        if ('a' \u003C= ch && ch \u003C= 'z') {\n            ++cnt[ch - 'a'];\n        }\n    }\n    return cnt;\n}\n",[15,1697,1698,1702,1706,1710,1715,1719,1723,1728,1733,1737,1741,1746],{"__ignoreMap":58},[62,1699,1700],{"class":64,"line":65},[62,1701,1172],{},[62,1703,1704],{"class":64,"line":71},[62,1705,68],{},[62,1707,1708],{"class":64,"line":77},[62,1709,81],{"emptyLinePlaceholder":80},[62,1711,1712],{"class":64,"line":84},[62,1713,1714],{},"std::array\u003Cint, 26> countLowerLetters(const std::string& s) {\n",[62,1716,1717],{"class":64,"line":90},[62,1718,1206],{},[62,1720,1721],{"class":64,"line":96},[62,1722,1658],{},[62,1724,1725],{"class":64,"line":102},[62,1726,1727],{},"        if ('a' \u003C= ch && ch \u003C= 'z') {\n",[62,1729,1730],{"class":64,"line":107},[62,1731,1732],{},"            ++cnt[ch - 'a'];\n",[62,1734,1735],{"class":64,"line":113},[62,1736,932],{},[62,1738,1739],{"class":64,"line":119},[62,1740,947],{},[62,1742,1743],{"class":64,"line":125},[62,1744,1745],{},"    return cnt;\n",[62,1747,1748],{"class":64,"line":131},[62,1749,191],{},[347,1751,1753],{"id":1752},"_8-对字符串排序后去重","8. 对字符串排序后去重",[23,1755,1756],{},"这个套路很常见，经常用于“规范化”一个字符串。",[53,1758,1760],{"className":55,"code":1759,"language":57,"meta":58,"style":58},"#include \u003Calgorithm>\n#include \u003Cstring>\n\nstd::string normalize(std::string s) {\n    std::sort(s.begin(), s.end());\n    s.erase(std::unique(s.begin(), s.end()), s.end());\n    return s;\n}\n",[15,1761,1762,1766,1770,1774,1779,1784,1789,1794],{"__ignoreMap":58},[62,1763,1764],{"class":64,"line":65},[62,1765,519],{},[62,1767,1768],{"class":64,"line":71},[62,1769,68],{},[62,1771,1772],{"class":64,"line":77},[62,1773,81],{"emptyLinePlaceholder":80},[62,1775,1776],{"class":64,"line":84},[62,1777,1778],{},"std::string normalize(std::string s) {\n",[62,1780,1781],{"class":64,"line":90},[62,1782,1783],{},"    std::sort(s.begin(), s.end());\n",[62,1785,1786],{"class":64,"line":96},[62,1787,1788],{},"    s.erase(std::unique(s.begin(), s.end()), s.end());\n",[62,1790,1791],{"class":64,"line":102},[62,1792,1793],{},"    return s;\n",[62,1795,1796],{"class":64,"line":107},[62,1797,191],{},[347,1799,1801],{"id":1800},"_9-分割字符串","9. 分割字符串",[23,1803,1804,1805,401],{},"标准库里最常见的是用 ",[15,1806,1807],{},"std::stringstream",[53,1809,1811],{"className":55,"code":1810,"language":57,"meta":58,"style":58},"#include \u003Csstream>\n#include \u003Cstring>\n#include \u003Cvector>\n\nstd::vector\u003Cstd::string> splitBySpace(const std::string& s) {\n    std::stringstream ss(s);\n    std::vector\u003Cstd::string> result;\n    std::string word;\n\n    while (ss >> word) {\n        result.push_back(word);\n    }\n    return result;\n}\n",[15,1812,1813,1818,1822,1827,1831,1836,1841,1846,1851,1855,1860,1865,1869,1874],{"__ignoreMap":58},[62,1814,1815],{"class":64,"line":65},[62,1816,1817],{},"#include \u003Csstream>\n",[62,1819,1820],{"class":64,"line":71},[62,1821,68],{},[62,1823,1824],{"class":64,"line":77},[62,1825,1826],{},"#include \u003Cvector>\n",[62,1828,1829],{"class":64,"line":84},[62,1830,81],{"emptyLinePlaceholder":80},[62,1832,1833],{"class":64,"line":90},[62,1834,1835],{},"std::vector\u003Cstd::string> splitBySpace(const std::string& s) {\n",[62,1837,1838],{"class":64,"line":96},[62,1839,1840],{},"    std::stringstream ss(s);\n",[62,1842,1843],{"class":64,"line":102},[62,1844,1845],{},"    std::vector\u003Cstd::string> result;\n",[62,1847,1848],{"class":64,"line":107},[62,1849,1850],{},"    std::string word;\n",[62,1852,1853],{"class":64,"line":113},[62,1854,81],{"emptyLinePlaceholder":80},[62,1856,1857],{"class":64,"line":119},[62,1858,1859],{},"    while (ss >> word) {\n",[62,1861,1862],{"class":64,"line":125},[62,1863,1864],{},"        result.push_back(word);\n",[62,1866,1867],{"class":64,"line":131},[62,1868,947],{},[62,1870,1871],{"class":64,"line":136},[62,1872,1873],{},"    return result;\n",[62,1875,1876],{"class":64,"line":142},[62,1877,191],{},[23,1879,1880],{},"如果按指定分隔符切分，比如逗号：",[53,1882,1884],{"className":55,"code":1883,"language":57,"meta":58,"style":58},"#include \u003Csstream>\n#include \u003Cstring>\n#include \u003Cvector>\n\nstd::vector\u003Cstd::string> splitByChar(const std::string& s, char delim) {\n    std::stringstream ss(s);\n    std::vector\u003Cstd::string> result;\n    std::string token;\n\n    while (std::getline(ss, token, delim)) {\n        result.push_back(token);\n    }\n    return result;\n}\n",[15,1885,1886,1890,1894,1898,1902,1907,1911,1915,1920,1924,1929,1934,1938,1942],{"__ignoreMap":58},[62,1887,1888],{"class":64,"line":65},[62,1889,1817],{},[62,1891,1892],{"class":64,"line":71},[62,1893,68],{},[62,1895,1896],{"class":64,"line":77},[62,1897,1826],{},[62,1899,1900],{"class":64,"line":84},[62,1901,81],{"emptyLinePlaceholder":80},[62,1903,1904],{"class":64,"line":90},[62,1905,1906],{},"std::vector\u003Cstd::string> splitByChar(const std::string& s, char delim) {\n",[62,1908,1909],{"class":64,"line":96},[62,1910,1840],{},[62,1912,1913],{"class":64,"line":102},[62,1914,1845],{},[62,1916,1917],{"class":64,"line":107},[62,1918,1919],{},"    std::string token;\n",[62,1921,1922],{"class":64,"line":113},[62,1923,81],{"emptyLinePlaceholder":80},[62,1925,1926],{"class":64,"line":119},[62,1927,1928],{},"    while (std::getline(ss, token, delim)) {\n",[62,1930,1931],{"class":64,"line":125},[62,1932,1933],{},"        result.push_back(token);\n",[62,1935,1936],{"class":64,"line":131},[62,1937,947],{},[62,1939,1940],{"class":64,"line":136},[62,1941,1873],{},[62,1943,1944],{"class":64,"line":142},[62,1945,191],{},[347,1947,1949],{"id":1948},"_10-压缩连续重复字符","10. 压缩连续重复字符",[23,1951,1952,1953,1956,1957,1309],{},"例如 ",[15,1954,1955],{},"\"aaabbc\""," 变成 ",[15,1958,1959],{},"\"a3b2c1\"",[53,1961,1963],{"className":55,"code":1962,"language":57,"meta":58,"style":58},"#include \u003Cstring>\n\nstd::string compressString(const std::string& s) {\n    if (s.empty()) {\n        return \"\";\n    }\n\n    std::string result;\n    for (size_t i = 0; i \u003C s.size(); ) {\n        size_t j = i;\n        while (j \u003C s.size() && s[j] == s[i]) {\n            ++j;\n        }\n        result += s[i];\n        result += std::to_string(j - i);\n        i = j;\n    }\n    return result;\n}\n",[15,1964,1965,1969,1973,1978,1983,1987,1991,1995,2000,2005,2010,2015,2020,2024,2029,2034,2039,2043,2047],{"__ignoreMap":58},[62,1966,1967],{"class":64,"line":65},[62,1968,68],{},[62,1970,1971],{"class":64,"line":71},[62,1972,81],{"emptyLinePlaceholder":80},[62,1974,1975],{"class":64,"line":77},[62,1976,1977],{},"std::string compressString(const std::string& s) {\n",[62,1979,1980],{"class":64,"line":84},[62,1981,1982],{},"    if (s.empty()) {\n",[62,1984,1985],{"class":64,"line":90},[62,1986,1444],{},[62,1988,1989],{"class":64,"line":96},[62,1990,947],{},[62,1992,1993],{"class":64,"line":102},[62,1994,81],{"emptyLinePlaceholder":80},[62,1996,1997],{"class":64,"line":107},[62,1998,1999],{},"    std::string result;\n",[62,2001,2002],{"class":64,"line":113},[62,2003,2004],{},"    for (size_t i = 0; i \u003C s.size(); ) {\n",[62,2006,2007],{"class":64,"line":119},[62,2008,2009],{},"        size_t j = i;\n",[62,2011,2012],{"class":64,"line":125},[62,2013,2014],{},"        while (j \u003C s.size() && s[j] == s[i]) {\n",[62,2016,2017],{"class":64,"line":131},[62,2018,2019],{},"            ++j;\n",[62,2021,2022],{"class":64,"line":136},[62,2023,932],{},[62,2025,2026],{"class":64,"line":142},[62,2027,2028],{},"        result += s[i];\n",[62,2030,2031],{"class":64,"line":148},[62,2032,2033],{},"        result += std::to_string(j - i);\n",[62,2035,2036],{"class":64,"line":153},[62,2037,2038],{},"        i = j;\n",[62,2040,2041],{"class":64,"line":159},[62,2042,947],{},[62,2044,2045],{"class":64,"line":165},[62,2046,1873],{},[62,2048,2049],{"class":64,"line":171},[62,2050,191],{},[347,2052,2054],{"id":2053},"_11-找到第一个不重复字符","11. 找到第一个不重复字符",[53,2056,2058],{"className":55,"code":2057,"language":57,"meta":58,"style":58},"#include \u003Cstring>\n#include \u003Cunordered_map>\n\nint firstUniqChar(const std::string& s) {\n    std::unordered_map\u003Cchar, int> freq;\n    for (char ch : s) {\n        ++freq[ch];\n    }\n\n    for (int i = 0; i \u003C static_cast\u003Cint>(s.size()); ++i) {\n        if (freq[s[i]] == 1) {\n            return i;\n        }\n    }\n    return -1;\n}\n",[15,2059,2060,2064,2068,2072,2077,2081,2085,2089,2093,2097,2102,2107,2112,2116,2120,2125],{"__ignoreMap":58},[62,2061,2062],{"class":64,"line":65},[62,2063,68],{},[62,2065,2066],{"class":64,"line":71},[62,2067,1639],{},[62,2069,2070],{"class":64,"line":77},[62,2071,81],{"emptyLinePlaceholder":80},[62,2073,2074],{"class":64,"line":84},[62,2075,2076],{},"int firstUniqChar(const std::string& s) {\n",[62,2078,2079],{"class":64,"line":90},[62,2080,1653],{},[62,2082,2083],{"class":64,"line":96},[62,2084,1658],{},[62,2086,2087],{"class":64,"line":102},[62,2088,1663],{},[62,2090,2091],{"class":64,"line":107},[62,2092,947],{},[62,2094,2095],{"class":64,"line":113},[62,2096,81],{"emptyLinePlaceholder":80},[62,2098,2099],{"class":64,"line":119},[62,2100,2101],{},"    for (int i = 0; i \u003C static_cast\u003Cint>(s.size()); ++i) {\n",[62,2103,2104],{"class":64,"line":125},[62,2105,2106],{},"        if (freq[s[i]] == 1) {\n",[62,2108,2109],{"class":64,"line":131},[62,2110,2111],{},"            return i;\n",[62,2113,2114],{"class":64,"line":136},[62,2115,932],{},[62,2117,2118],{"class":64,"line":142},[62,2119,947],{},[62,2121,2122],{"class":64,"line":148},[62,2123,2124],{},"    return -1;\n",[62,2126,2127],{"class":64,"line":153},[62,2128,191],{},[347,2130,2132],{"id":2131},"_12-比较两个字符串的公共前缀","12. 比较两个字符串的公共前缀",[53,2134,2136],{"className":55,"code":2135,"language":57,"meta":58,"style":58},"#include \u003Cstring>\n\nstd::string commonPrefix(const std::string& a, const std::string& b) {\n    size_t i = 0;\n    while (i \u003C a.size() && i \u003C b.size() && a[i] == b[i]) {\n        ++i;\n    }\n    return a.substr(0, i);\n}\n",[15,2137,2138,2142,2146,2151,2156,2161,2166,2170,2175],{"__ignoreMap":58},[62,2139,2140],{"class":64,"line":65},[62,2141,68],{},[62,2143,2144],{"class":64,"line":71},[62,2145,81],{"emptyLinePlaceholder":80},[62,2147,2148],{"class":64,"line":77},[62,2149,2150],{},"std::string commonPrefix(const std::string& a, const std::string& b) {\n",[62,2152,2153],{"class":64,"line":84},[62,2154,2155],{},"    size_t i = 0;\n",[62,2157,2158],{"class":64,"line":90},[62,2159,2160],{},"    while (i \u003C a.size() && i \u003C b.size() && a[i] == b[i]) {\n",[62,2162,2163],{"class":64,"line":96},[62,2164,2165],{},"        ++i;\n",[62,2167,2168],{"class":64,"line":102},[62,2169,947],{},[62,2171,2172],{"class":64,"line":107},[62,2173,2174],{},"    return a.substr(0, i);\n",[62,2176,2177],{"class":64,"line":113},[62,2178,191],{},[46,2180,2181],{"id":2181},"一眼就该想到的套路",[23,2183,2184],{},"遇到字符串题时，可以先想这几个方向：",[2186,2187,2188,2191,2194,2197,2203,2208,2213,2216],"ol",{},[30,2189,2190],{},"只关心字符出现次数：用数组或哈希表统计。",[30,2192,2193],{},"只关心字符组成是否一样：排序后比较，或者计数比较。",[30,2195,2196],{},"涉及左右对称：双指针。",[30,2198,2199,2200,401],{},"涉及批量删字符：",[15,2201,2202],{},"erase + remove_if",[30,2204,2205,2206,401],{},"涉及大小写统一：",[15,2207,630],{},[30,2209,2210,2211,401],{},"涉及按规则重排：",[15,2212,535],{},[30,2214,2215],{},"涉及连续段处理：双指针或分组遍历。",[30,2217,2218,2219,673,2221,673,2224,401],{},"涉及查找某段子串：",[15,2220,353],{},[15,2222,2223],{},"rfind",[15,2225,2226],{},"substr",[46,2228,2229],{"id":2229},"常见坑",[347,2231,350,2233,2235],{"id":2232},"_1-remove-不是真删",[15,2234,672],{}," 不是真删",[23,2237,2238],{},"错误理解：",[53,2240,2242],{"className":55,"code":2241,"language":57,"meta":58,"style":58},"std::remove(s.begin(), s.end(), ' ');\n",[15,2243,2244],{"__ignoreMap":58},[62,2245,2246],{"class":64,"line":65},[62,2247,2241],{},[23,2249,2250],{},"正确写法：",[53,2252,2253],{"className":55,"code":699,"language":57,"meta":58,"style":58},[15,2254,2255],{"__ignoreMap":58},[62,2256,2257],{"class":64,"line":65},[62,2258,699],{},[347,2260,405,2262,673,2265,673,2268,673,2271,2274,2275],{"id":2261},"_2-tolower-toupper-isdigit-isspace-最好接-unsigned-char",[15,2263,2264],{},"tolower",[15,2266,2267],{},"toupper",[15,2269,2270],{},"isdigit",[15,2272,2273],{},"isspace"," 最好接 ",[15,2276,2277],{},"unsigned char",[23,2279,2280],{},"推荐这样写：",[53,2282,2284],{"className":55,"code":2283,"language":57,"meta":58,"style":58},"std::tolower(static_cast\u003Cunsigned char>(ch));\n",[15,2285,2286],{"__ignoreMap":58},[62,2287,2288],{"class":64,"line":65},[62,2289,2283],{},[23,2291,2292],{},"这是为了避免某些编译器和字符集环境下的未定义行为。",[347,2294,432,2296,2298],{"id":2295},"_3-sort-需要随机访问迭代器",[15,2297,535],{}," 需要随机访问迭代器",[23,2300,2301],{},"所以它可以直接排：",[27,2303,2304,2308,2313],{},[30,2305,2306],{},[15,2307,34],{},[30,2309,2310],{},[15,2311,2312],{},"std::vector",[30,2314,2315],{},[15,2316,2317],{},"std::deque",[23,2319,2320,2321,401],{},"但不能直接排 ",[15,2322,2323],{},"std::list",[347,2325,2327],{"id":2326},"_4-修改字符串时要注意迭代器失效","4. 修改字符串时要注意迭代器失效",[23,2329,2330,2331,2334,2335,2334,2337,2340],{},"比如 ",[15,2332,2333],{},"insert","、",[15,2336,684],{},[15,2338,2339],{},"replace"," 后，之前保存的迭代器或下标可能不再可靠，尤其是在循环里边删边改时要小心。",[46,2342,2343],{"id":2343},"一个小结",[23,2345,2346,2348,2349,2351],{},[15,2347,34],{}," 负责“存”和“改”，",[15,2350,40],{}," 负责“批量处理”和“套路化操作”。",[23,2353,2354],{},"如果你把下面这些操作练熟，大多数基础字符串题都会顺很多：",[27,2356,2357,2362,2367,2371,2374,2377],{},[30,2358,2359],{},[15,2360,2361],{},"find \u002F substr \u002F replace",[30,2363,2364],{},[15,2365,2366],{},"sort \u002F reverse \u002F count \u002F transform",[30,2368,2369],{},[15,2370,2202],{},[30,2372,2373],{},"双指针",[30,2375,2376],{},"哈希计数",[30,2378,2379],{},"排序去重",[23,2381,2382],{},"真正写题时，不要一上来就手搓最底层循环，先想标准库里有没有现成套路，这样代码更短，也更不容易出错。",[2384,2385,2386],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":58,"searchDepth":71,"depth":71,"links":2388},[2389,2391,2402,2421,2435,2436,2445],{"id":48,"depth":71,"text":2390},"string 常用操作速查",{"id":342,"depth":71,"text":2392,"children":2393},"string 里的几个高频细节",[2394,2396,2398,2400],{"id":349,"depth":77,"text":2395},"1. find 找不到时返回 npos",{"id":404,"depth":77,"text":2397},"2. substr(pos, len) 的第二个参数是长度，不是右边界",{"id":431,"depth":77,"text":2399},"3. operator[] 不检查越界，at() 会检查",{"id":463,"depth":77,"text":2401},"4. 频繁拼接长字符串时，建议先 reserve",{"id":506,"depth":71,"text":2403,"children":2404},"\u003Calgorithm> 在字符串里的高频招式",[2405,2407,2409,2411,2413,2415,2417,2419],{"id":531,"depth":77,"text":2406},"1. 排序 sort",{"id":572,"depth":77,"text":2408},"2. 翻转 reverse",{"id":599,"depth":77,"text":2410},"3. 计数 count",{"id":626,"depth":77,"text":2412},"4. 批量变换 transform",{"id":668,"depth":77,"text":2414},"5. 删除类操作 remove \u002F remove_if",{"id":739,"depth":77,"text":2416},"6. 去重 unique",{"id":780,"depth":77,"text":2418},"7. 条件判断 all_of \u002F any_of \u002F none_of",{"id":820,"depth":77,"text":2420},"8. 查找满足条件的字符 find_if",{"id":873,"depth":71,"text":873,"children":2422},[2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434],{"id":879,"depth":77,"text":880},{"id":1100,"depth":77,"text":1101},{"id":1271,"depth":77,"text":1272},{"id":1362,"depth":77,"text":1363},{"id":1460,"depth":77,"text":1461},{"id":1542,"depth":77,"text":1543},{"id":1620,"depth":77,"text":1621},{"id":1752,"depth":77,"text":1753},{"id":1800,"depth":77,"text":1801},{"id":1948,"depth":77,"text":1949},{"id":2053,"depth":77,"text":2054},{"id":2131,"depth":77,"text":2132},{"id":2181,"depth":71,"text":2181},{"id":2229,"depth":71,"text":2229,"children":2437},[2438,2440,2442,2444],{"id":2232,"depth":77,"text":2439},"1. remove 不是真删",{"id":2261,"depth":77,"text":2441},"2. tolower \u002F toupper \u002F isdigit \u002F isspace 最好接 unsigned char",{"id":2295,"depth":77,"text":2443},"3. sort 需要随机访问迭代器",{"id":2326,"depth":77,"text":2327},{"id":2343,"depth":71,"text":2343},"md",{},"\u002Fcpp\u002Ffeatures\u002Fstring-和-algorithm",{"title":5,"description":25},"cpp\u002Ffeatures\u002Fstring 和 algorithm","HGOOhkvsfBUr4ctO82nE7YfsmgLqm1GwOubIHGnrwqo",1791042462815]