C++ `string` 用法全解(算法竞赛向)

📌 基础操作

#include <string>
using namespace std;

string s1;              // 空字符串
string s2 = "hello";    // 直接初始化
string s3(5, 'a');      // "aaaaa"
string s4(s2, 1, 3);    // "ell"(从下标1开始取3个字符)

🚀 高频使用操作

1. 访问元素

s[0] = 'H';      // 修改首字符(不检查越界)
s.at(1) = 'E';   // 带越界检查的访问
s.front();       // 首字符(等价于s[0])
s.back();        // 末尾字符

2. 字符串拼接

string s = "Hello";
s += " World";     // "Hello World"
s.append("!!!");   // "Hello World!!!"
s.push_back('!');  // 追加单个字符

3. 子串操作

string sub = s.substr(6, 5);  // "World"(位置6开始取5个字符)
s.substr(6);                  // "World!!!"(从6到末尾)

4. 查找操作

int pos = s.find("World");    // 返回首次出现位置(6)
pos = s.find("word");         // string::npos(未找到)
pos = s.rfind("l");           // 从后向前查找(返回最后一个'l'的位置)

🔧 算法竞赛实用技巧

1. 快速分割字符串

string data = "apple,orange,banana";
size_t pos = 0;
while ((pos = data.find(',')) != string::npos) {
    string token = data.substr(0, pos);
    cout << token << endl;
    data.erase(0, pos + 1);
}
cout << data << endl;  // 最后一个元素

2. 字符串与数值转换

// C++11标准方法
int num = stoi("42");
double d = stod("3.14");
string s_num = to_string(123);

// 传统C方法(更快但危险)
int num = atoi("42");  // 需要c_str()

3. 大小写转换

for (char &c : s) {
    c = toupper(c);  // 转大写
    // c = tolower(c);  // 转小写
}

4. 字符串流处理

#include <sstream>
string input = "123 3.14 hello";
istringstream iss(input);
int a; double b; string c;
iss >> a >> b >> c;  // a=123, b=3.14, c="hello"

⚡️ 性能优化技巧

1. 预分配空间

string s;
s.reserve(1000);  // 预分配内存,避免频繁扩容

2. 移动语义(C++11+)

string get_string() {
    string tmp(1000000, 'x');
    return tmp;  // 触发移动构造而非拷贝
}

🏆 竞赛常见应用

1. 回文判断

bool is_palindrome(const string &s) {
    return equal(s.begin(), s.end(), s.rbegin());
}

2. 字符串旋转

string rotate(const string &s, int k) {
    string res = s;
    rotate(res.begin(), res.begin() + k % res.size(), res.end());
    return res;
}

3. KMP算法实现

vector<int> compute_lps(const string &pattern) {
    vector<int> lps(pattern.size());
    for (int i = 1, len = 0; i < pattern.size(); ) {
        if (pattern[i] == pattern[len]) lps[i++] = ++len;
        else if (len) len = lps[len-1];
        else lps[i++] = 0;
    }
    return lps;
}

⚠️ 常见错误

  1. 越界访问

    string s = "hello";
    char c = s[10];  // 未定义行为!
    
  2. 混淆size()和length()

    // 虽然功能相同,但建议统一使用size()
    for (int i = 0; i < s.size(); ++i) {...}
    
  3. 忽略npos的类型

    if (s.find("x") == -1) {...}  // 错误!npos是size_t类型
    if (s.find("x") == string::npos) {...}  // 正确
    

📊 与其他语言对比

操作C++ (string)Python (str)Java (String)
拼接s1 + s2s1 + s2s1.concat(s2)
查找子串find()find()indexOf()
长度s.size()len(s)s.length()
切片substr(pos, len)s[start:end]substring(b,e)

📌 竞赛建议:将常用字符串操作封装成函数模板,如split()/join(),可节省编码时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值