← 返回首页

C++数组与字符串处理:从暴力到优雅,让你的代码跑得更快

C++数组与字符串处理:从暴力到优雅,让你的代码跑得更快
C++数组与字符串处理:从暴力到优雅,让你的代码跑得更快

想象一下,你在竞赛中遇到一个字符串匹配题,如果用暴力方法逐个比较字符,1000长度的串就会让你直接TLE。但如果你学会前缀和KMP算法,同样的题目可能只需要O(n)时间就能解决。今天咱们就从最基础的数组与字符串操作说起,这些技巧就像信息学竞赛的"基本功",用得越溜,越能节省宝贵的思考时间。


核心概念讲解

1. 数组

数组是连续内存存储的同类型数据集合,通过索引快速访问(时间复杂度O(1))。

关键点

  • int arr[n]:动态数组(C++98标准不支持,需用vector)

  • arr[i]:第i个元素的值(下标从0开始)

  • 越界访问会导致UB(未定义行为),竞赛中常引发WA

图示:


内存布局:

[arr[0], arr[1], arr[2]] → 实际地址:base, base+4, base+8

2. 字符串

string类封装了字符数组,支持[]访问、.size()等方法。

注意

  • C风格字符串char str[]\0结尾

  • 竞赛中stringchar*更安全,避免手动释放内存

3. 常用操作

  • 遍历:for(int i=0; i<n; i++)

  • 子串提取:s.substr(pos,len)

  • 查找:find()返回位置(找不到返回string::npos


C++代码示例


#include <bits/stdc++.h>

using namespace std;

// 1. 统计字符串中元音字母数量

void countVowels() {

string s = "Hello World!";

int cnt = 0;

for(char c : s) { // 范围for简化遍历

if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') cnt++;

}

cout << "元音数量: " << cnt << endl; // 输出3

}

// 2. 二维数组转置(矩阵转置)

void transposeMatrix(vector<vector<int>>& mat) {

int n = mat.size();

vector<vector<int>> trans(n, vector<int>(n));

for(int i=0; i<n; i++)

for(int j=0; j<n; j++)

trans[j][i] = mat[i][j]; // 行列交换

}

// 3. 字符串反转(双指针法)

void reverseString(string &s) {

int l=0, r=s.size()-1;

while(l<r) swap(s[l++], s[r--]);

}

int main() {

countVowels(); // 测试函数

vector<vector<int>> mat = {{1,2},{3,4}};

transposeMatrix(mat); // 输出{{1,3},{2,4}}

string str = "abc";

reverseString(str);

cout << str; // cba

return 0;

}

算法分析

| 操作 | 时间复杂度 | 空间复杂度 |

|—————|—————–|————|

| 数组遍历 | O(n) | O(1) |

| 字符串查找 | O(n) (朴素算法) | O(1) |

| 二维矩阵转置 | O(n²) | O(n²) |

适用场景

  • 需要频繁随机访问时用数组(如前缀和预处理)

  • 字符串处理优先用string而非C风格字符串

局限性

  • 静态数组大小固定,动态扩容需谨慎(vector更灵活)

经典例题

  1. P1617 字符串匹配(洛谷)

题目描述:给定模式串和文本串,统计出现次数。

思路:先实现暴力匹配(O(mn)),再尝试优化(如KMP算法)。

  1. CF151B Beautiful Year(AtCoder)

题目描述:找出最小的大于给定年份且各位数字不重复的年份。

关键:将年份转为字符串处理,逐位检查。


推荐练习

  1. P2666 【模板】KMP算法(简单版)

(掌握next数组的构建,为后续学习打基础)

  1. P5357 [TJOI2017] 字符串(中等)

(需要综合运用字符串哈希和前缀和)

  1. CF1057D Permutation Checker(Hard)

(进阶:结合数组和字符串处理)


小结

今天你学会了:数组的高效访问、string的基本操作,以及如何通过这些技巧简化问题。记住,好代码不是写出来的,是改出来的——多动手调试,下次遇到字符串题,试试用find()代替循环!

下期预告:字符串哈希技术——让"字符串相等判断"从O(n)变成O(1),敬请期待!