零碎

字符串

ASCII码表

常见ASCII范围

小写字母在大写字母后面,因此大写字母转换为小写字母需要+32

字符类型 ASCII 码范围 字符范围
数字 0-9 48-57 '0'=48, '9'=57
大写字母 A-Z 65-90 'A'=65, 'Z'=90
小写字母 a-z 97-122 'a'=97, 'z'=122
空格 32 ' '

判断是否是大写/小写字母

  • c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'
  • str[i] >= 65 && str[i] <= 90 || str[i] >= 97 && str[i] <= 122
  • tolower或toupper
  • 加减32手动转换

字符与数字互转

  • 字符转数字'0'-'9'0-9

    char c = '7';
    int num = c - '0';  // num = 7
    
  • 数字转字符0-9'0'-'9'

    int num = 5;
    char c = num + '0';  // c = '5'
    

字符串转数值 stoi / stol

string s = "456";
int num = stoi(s); // 456

alt

字符串流

字符串流 #include <sstream> 字符串与数据类型的转换(istringstream读字符串,ostringstream写字符串)

基本步骤

  1. 将字符串绑定到输入流istringstream iss(str);
  2. 按需提取数据:使用 >> 操作符(自动跳过空白符)。
  3. 处理剩余数据或错误:检查流状态。
string line = "100 3.14 hello";
istringstream iss(line);
int a;
double b;
string c;
iss >> a >> b >> c;  // a=100, b=3.14, c="hello"
string line = "2023,12,31";
istringstream iss(line);
int year, month, day;
char comma;
iss >> year >> comma >> month >> comma >> day;  // 显式读取逗号

循环读取未知数量的数据

string line = "1 2 3 4 5";
istringstream iss(line);
vector<int> nums;
int x;
while (iss >> x) {   // 直到流无法提取数据
    nums.push_back(x);
}
// nums = [1,2,3,4,5]

输入一行 "Name:Alice Age:25 Score:95.5",提取姓名、年龄、分数。

string line = "Name:Alice Age:25 Score:95.5";
istringstream iss(line);
string name, tmp;
int age;
double score;

iss >> tmp >> name >> tmp >> age >> tmp >> score;
// name="Alice", age=25, score=95.5

string的用法

substr, find, insert, replace, erase,并且与vector一样都有push_back和pop_back方法

函数 功能说明 示例代码
size() / length() 返回字符串长度 int len = s.size();
empty() 判断字符串是否为空 if (s.empty()) { ... }
clear() 清空字符串内容 s.clear();
push_back(char c) 尾部添加字符 s.push_back('!');
pop_back() 删除尾部字符 s.pop_back();
substr(pos, len) 截取子字符串 string sub = s.substr(0, 3);
find(str) 查找子串位置(返回索引或 npos int pos = s.find("abc");
replace(pos, len, new_str) 替换子串 s.replace(2, 2, "xyz");
append(str) 追加字符串 s.append("world");
insert(pos, str) 在指定位置插入字符串 s.insert(5, " ");
erase(pos, len) 删除子串 s.erase(3, 2);
  • insert插入字符串

    string& insert(size_t pos, const string& str);	// 在位置 pos 处插入字符串 str
    string& insert(size_t pos, size_t n, char c);	// 在位置 pos 处插入 n 个字符 c,即插入多个重复字符(n=1就是一个)
    void insert(iterator p, InputIterator first, InputIterator last);	// 在迭代器 p 处插入范围 [first, last) 的字符
    

    第一个参数是插入位置(下标或迭代器),后面参数是插入字符串的首尾迭代器/目标字符串

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string str = "abcxyz", str2 = "opq";
        // 在str的第4个位置插入str2即opq,后面两个参数是待插字符串的首尾迭代器,左闭右开 
        str.insert(str.begin() + 3, str2.begin(), str2.end());
        cout << str << endl;
        return 0;
    }
    

    第一个参数表示在何处插入,第二个参数表示插入的字符的数量

    // 在高位补0对齐位数
    while (s1.size() < s2.size()) {
    	s1.insert(0, 1, '0');
    }
    while (s1.size() > s2.size()) {
    	s2.insert(0, 1, '0');
    }
    
  • erase删除单个字符或一个区间内字符

    string& erase(size_t pos = 0, size_t len = npos);		// 删除从位置 pos 开始的 len 个字符(默认删除到末尾)
    iterator erase(const_iterator p);					   // 删除迭代器 p 指向的字符
    iterator erase(const_iterator first, const_iterator last); // 删除 [first, last) 范围内的字符
    

    一个参数是删除一个字符;

    两个参数是将首尾迭代器内的字符全部删除,或从下标开始删除len个字符

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string str = "abcdefg";
        // 从第3个字符一直删到最后一个字符,左闭右开,只剩下头2个字符和最后一个字符 
        str.erase(str.begin() + 2, str.end() - 1);
        cout << str << endl;
        return 0;
    }
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string str = "abcdefg";
        // 从第4个位置开始删除2个字符 
        str.erase(3, 2);
        cout << str << endl;
        return 0;
    }
    
  • 查找

    size_t find(const string& str, size_t pos = 0) const; // 默认一个参数从头开始找,也可以指定第二个参数参数从pos开始找
    

    查找返回起始下标,没找到返回string::npos(一个参数目标字符串是从起始位置开始查找返回第一次出现的下标,两个参数从start_pos开始找目标字符串)

    while ((pos = s.find(temp, pos)) != string::npos) {
    	count[temp]++;
    	pos++;
    }
    
  • 替换

    string& replace(size_t pos, size_t len, const string& str);		// 将字符串从位置 pos 开始的 len 个字符替换为 str
    string& replace(const_iterator first, const_iterator last, const string& str);	// 替换迭代器 [first, last) 范围内的内容为 str
    

    替换是从第一个参数的下标开始,将长度为第二个参数的子串替换为第三个参数的目标字符串(有可能替换的目标字符串超过子串长度,也可能少于)

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string str = "Maybe you will turn around.";
        string str2 = "will not";
        string str3 = "surely";
        //  将str从第11个位置开始的4个长度子串will替换成str2 will not 
        cout << str.replace(10, 4, str2) << endl;
        //  将str的开头到第6个位置子串Maybe替换成str3 surly,前两个参数左闭右开 
        cout << str.replace(str.begin(), str.begin() + 5, str3) << endl;
        return 0;
    }
    

    find与replace组合使用

    string s = "Hello World";
    size_t pos = s.find("World");
    if (pos != string::npos) {
        s.replace(pos, 5, "C++");  // 替换"World"为"C++"
    }
    // 结果:"Hello C++"
    
  • 截取子串

    str.substr(k)从下标为k除截取到末尾的字符串,str.substr(k, m)从下标为k的字符除截取长度为m的字符串

    string sub = s2.substr(6, 3); // 从索引6开始截取3字符:"CPP"
    

典型应用

统计子串出现次数

int count = 0;
size_t pos = 0;
while ((pos = s.find("ab", pos)) != string::npos) {
    count++;
    pos += 2; // 跳过已匹配的子串
    // s.erase(pos, 2); // 或直接删掉
}

删除子串中所有特定字符串

find与erase配合使用,循环删除子串中所有特定字符串

#include <string>
#include <iostream>
using namespace std;

int main() {
    string str1, str2;
    while (cin >> str1 >> str2) {
        int pos = 0;
        while ((pos = str1.find(str2)) != string::npos) {
            str1.erase(pos, str2.size());
        }
        cout << str1 << endl;
    }
    return 0;
}

在高位补0对齐位数

while (s1.size() < s2.size()) {
	s1.insert(0, 1, '0');
}

统计单词数

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {
    string line;
    getline(cin, line);
    istringstream iss(line);
    string word;
    int count = 0;
    while (iss >> word) { 	// 自动按空格分割
        count++;
    }
    cout << count << endl;
    return 0;
}

统计字符频率

string s;
freq[100] = {0};
for (char c : s) {
    freq[c]++;
}

判断回文

bool isPalindrome(const string& s) {
    int left = 0, right = s.size() - 1;
    while (left < right) {
        if (s[left++] != s[right--]) return false;
    }
    return true;
}

注意事项

  • cin和scanf都是按空格读取

  • 用fgets读取一整行需要pop_back()去除末尾的换行符

    char buf[10];
    fgets(buf, sizeof(buf), stdin);
    string s;
    s = buf;
    s.pop_back();
    
  • 用getline配合cin读取一整行

    string s;
    getline(cin, s);
    
  • 混合输入数字和字符串时,需处理残留的换行符(或使用getchar();

    int n;
    cin >> n;
    cin.ignore(); // 清除换行符
    string s;
    getline(cin, s);
    
    int n;
    scanf("%d", &n);
    getchar();
    char str[20];
    fgets(str, 20, stdin);
    
  • cin >> str;(或用%s读入字符数组再赋值给string,随后使用string的成员函数)

  • cout << str; (printf("%s\n", str.c_str());

常用容器

vector

push_back, insert, pop_back, erase

操作分类方法/操作示例代码注意事项
初始化 默认初始化 vector<int> v1; 初始为空容器
添加元素 尾部插入元素 v.push_back(10); v.emplace_back(10);(C++11+,效率更高) 动态扩容可能触发内存重新分配(复杂度均摊为O(1))
指定位置插入元素 v.insert(v.begin() + 2, 20); 插入位置后的元素需后移,避免频繁操作
删除元素 尾部删除元素 v.pop_back(); 容器非空时使用
删除指定位置元素 v.erase(v.begin() + 1); 删除位置后的元素需前移
删除指定范围元素 v.erase(v.begin(), v.begin() + 2); 范围左闭右开
清空容器 v.clear(); 容器变为空,但内存可能保留(可用shrink_to_fit()释放)
访问元素 通过下标访问 int x = v[0]; 不检查越界(可能导致未定义行为)
安全访问(检查越界) int y = v.at(0); 越界时抛出out_of_range异常
访问首尾元素 int front = v.front(); int back = v.back(); 容器非空时使用
遍历容器 从头使用迭代器遍历 for (auto it = v.begin(); it != v.end(); ++it) { ... } 支持const_iterator(只读遍历)
从后使用迭代器遍历 for (auto it = v.rbegin(); it != v.rend(); ++it) { ... } 支持const_iterator(只读遍历)
范围for循环(C++11+) for (int num : v) { ... } 修改元素需用引用:for (int& num : v)
容量操作 获取元素数量 int size = v.size(); 实际元素个数

map

insert, find, erase

函数 功能说明 示例代码
insert({key, value}) 插入键值对 m.insert({"apple", 2});
operator[] 访问或插入元素(若键不存在则创建) m["apple"] = 3;
find(key) 查找键,返回迭代器(未找到返回 end() auto it = m.find("apple");
count(key) 统计键是否存在(0或1) if (m.count("apple")) { ... }
erase(key) 删除指定键的元素 m.erase("apple");
size() 返回元素个数 int n = m.size();
empty() 判断是否为空 if (m.empty()) { ... }
clear() 清空所有元素 m.clear();

stack与queue

都有push与pop方法、empty和size方法,因为队列队尾入队,队头出队因此有front与back方法,栈仅能访问栈顶元素,只有top方法

map与set

find, insert, erase

pair

下面的操作与map非常像,包括花括号赋值、迭代器遍历first与second、比较大的区别是map默认按键的升序排序

基本声明与初始化

定义 vector 存储 pair

#include <vector>
#include <utility>  // pair 的头文件

// 声明一个存储 int-string 键值对的 vector
vector<pair<int, string>> vec;

// 初始化列表直接赋值
vector<pair<int, string>> vec_init = {
    {1, "apple"},
    {2, "banana"},
    {3, "cherry"}
};

添加元素

vec.push_back(make_pair(4, "orange"));  // 使用 make_pair
vec.emplace_back(5, "grape");           // 更高效的 emplace_back(C++11)

遍历与访问

通过下标访问

pair<int, string>& first_pair = vec[0];
cout << first_pair.first << ": " << first_pair.second << endl;  // 输出 1: apple

遍历所有元素

for (const auto& p : vec) {
    cout << p.first << " - " << p.second << endl;
}

使用迭代器

for (auto it = vec.begin(); it != vec.end(); ++it) {
    cout << it->first << " | " << it->second << endl;
}

容器集合

容器名称 特点描述 常用操作 典型应用场景
vector 动态数组,支持快速随机访问 push_back(), pop_back(), insert(), erase(), [], size(), empty() 需要动态数组、频繁随机访问
queue 先进先出(FIFO)队列 push(), pop(), front(), back(), size(), empty() BFS、缓冲区管理
stack 后进先出(LIFO)栈 push(), pop(), top(), size(), empty() DFS、括号匹配、表达式求值
priority_queue 优先队列(默认最大堆),堆顶元素优先级最高 push(), pop(), top(), size(), empty() Dijkstra算法、贪心策略、Top-K问题
deque 双端队列,两端高效插入/删除,支持随机访问 push_front(), push_back(), pop_front(), pop_back(), [], insert() 滑动窗口、双向操作
set 有序集合(红黑树实现),元素唯一且有序 insert(), erase(), find(), count(), lower_bound(), upper_bound() 去重、有序数据维护
multiset 类似set,但允许重复元素 set 允许重复的有序集合
map 有序键值对(红黑树实现),键唯一且按序存储 insert(), erase(), find(), [], count(), lower_bound() 字典、键值映射
multimap 类似map,但允许重复键 map 允许重复键的映射
unordered_set 哈希集合,元素唯一但无序 insert(), erase(), find(), count() 快速去重、无需顺序
unordered_map 哈希表,键唯一但无序 insert(), erase(), find(), [], count() 快速键值查找
pair 存储两个值的模板类,常用于组合数据 直接访问firstsecond成员 存储坐标、键值对(如边权)
string 字符串容器,支持动态操作 append(), substr(), find(), push_back(), size(), empty() 字符串处理、文本操作

常用的STL算法

比较常用的有sort, find, reverse, swap, erase

算法名称 功能描述 参数示例(C++) 返回类型/行为 典型应用场景
sort 对序列进行排序(默认升序) sort(v.begin(), v.end(), cmp) 无返回值,直接修改原序列 通用排序
stable_sort 稳定排序(相等元素顺序不变) stable_sort(v.begin(), v.end(), cmp) 同上 需要保留相等元素原始顺序
lower_bound 在有序序列中返回第一个≥目标值的迭代器 lower_bound(v.begin(), v.end(), x) 指向目标位置的迭代器 二分查找、范围查询
upper_bound 在有序序列中返回第一个>目标值的迭代器 upper_bound(v.begin(), v.end(), x) 同上 范围查询、统计出现次数
binary_search 检查有序序列中是否存在某个值 binary_search(v.begin(), v.end(), x) 返回bool(存在为true 快速存在性判断
find 在序列中查找第一个等于目标值的元素 find(v.begin(), v.end(), x) 指向该元素的迭代器(未找到则返回end() 线性搜索
count 统计序列中等于目标值的元素个数 count(v.begin(), v.end(), x) 返回匹配的个数 统计频率
reverse 反转序列中的元素顺序 reverse(v.begin(), v.end()) 无返回值,直接修改原序列 字符串反转、对称操作
unique 移除相邻重复元素(需先排序) unique(v.begin(), v.end()) 返回去重后的新逻辑结尾迭代器(需配合erase使用) 去重(需先排序)
next_permutation 生成序列的下一个字典序排列 next_permutation(v.begin(), v.end()) 返回bool(若已是最后排列则返回false 全排列生成(如N皇后问题)
max_element 返回序列中最大元素的迭代器 max_element(v.begin(), v.end()) 指向最大元素的迭代器 找最大值/最小值
accumulate 计算序列的累加值(可自定义操作) accumulate(v.begin(), v.end(), init, op) 返回累加结果(init为初始值,op为二元操作函数) 求和、自定义聚合操作
fill 将序列填充为指定值 fill(v.begin(), v.end(), x) 无返回值 初始化数组
copy 复制序列内容到目标位置 copy(src.begin(), src.end(), dest.begin()) 返回目标序列的结束迭代器 数组复制
swap 交换两个对象的值 swap(a, b) 无返回值 变量交换、容器内容交换
transform 对序列中每个元素应用函数并存储结果 transform(in.begin(), in.end(), out.begin(), op) 返回输出序列的结束迭代器 数据转换(如大小写转换)
erase 从容器中删除元素(需结合容器方法使用) v.erase(it)v.erase(start, end) 返回删除后的下一个有效迭代器 动态删除元素
rotate 循环左移序列元素(如将[a,b,c,d]变为[b,c,d,a] rotate(v.begin(), new_start, v.end()) 无返回值 循环移位、字符串旋转
全部评论

相关推荐

03-17 14:20
安徽大学 C++
🎓学历背景:末流211硕士,学院本👨‍💻意向职位:C/C++简历应该如何优化啊
Aline2021:感觉除了硕士学历没什么竞争力啊,你会的这些技术栈一个本科生也会,他价格还比你便宜,你要展现出自己的竞争力
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务