CPP Syntax Bits and Bobs

对在Leetcode刷题过程中遗漏的CPP语法进行补充,内容较为零碎,就先委屈一点挤挤吧😀,可能较多的是C++14/17新特性,如若后期深入学习Modern CPP,可能就会删减单拉出去为一章节了,敬请期待!

(I)auto

auto是一个类型占位符,它指示编译器自动推导变量的类型。编译器会根据初始化表达式(等号右边的值)来确定auto变量的实际类型。

1
2
3
int x=10;
//等效于
auto x=10;
1
2
3
double y=10.0;
//等效于
auto y=10.0;
1
2
3
4
auto f = 3.14;  //double
auto s("hello"); //const char*
auto z = new auto(9); //int *
auto x1 = 5, x2 = 5.0, x3 = 'r'; //错误,必须是初始化为同一类型

但是显然,这么简单的类型推导,auto的作用并不大。

auto常用场景

auto的真正作用是在复杂的类型推导中,例如迭代器lambda表达式等,使程序更清晰易读。

简化复杂类型声明

1
2
3
4
5
std::vector<int> v = {1, 2, 3, 4, 5};
// for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << std::endl;
}

范围 for 循环

1
2
3
for (auto element : container) {
// 使用 element
}

Lambda 表达式

1
auto lambda = [](int x, int y) { return x + y; };

Limitations

  • 必须初始化
1
auto x;  // 错误:无法推导类型
  • 不能用于函数参数
1
2
3
void func(auto x) {  // 错误:不能用于函数参数
// ...
}
  • 多变量声明需类型一致
1
auto x = 10, y = 20.0;  // 错误:类型不一致

(II)结构化绑定

结构化绑定(Structured Bindings)是C++17这是一个非常实用的语法特性,它允许我们同时声明多个变量并从一个聚合类型(如struct、pair 等)中提取其成员,使代码更加简洁易读。

1
auto [var1, var2, ...] = 聚合类型;

解构函数

结构化绑定可以非常方便地处理多个返回值的函数,例如返回tuplepair的函数。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <tuple>
using namespace std;
tuple<int,int> calculate(int a,int b) {
return {a+b,a-b};
}
int main() {
auto [add,sub]=calculate(3,1);
cout<<add<<endl;
cout<<sub<<endl;
return 0;
}

解构结构体(类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;
struct Product {
string name;
double price;
int stock;
};
Product apple={"apple",4.1,50};

int main() {
auto [name,val,stock]=apple;
cout<<name<<val<<stock;
return 0;
}

解构数组(静态)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
int main() {
int numbers[5] = {10, 20, 30, 40, 50};
auto [a, b, c, d, e] = numbers;
cout << "Array elements: " << a << ", " << b << ", " << c << ", " << d << ", " << e << std::endl;

// 二维数组解构
int matrix[2][2] = {{1, 2}, {3, 4}};
auto [row1, row2] = matrix;
auto [r1c1, r1c2] = row1;
auto [r2c1, r2c2] = row2;
cout << "Matrix: " << r1c1 << "," << r1c2 << " | " << r2c1 << "," << r2c2 << endl;

return 0;
}

遍历容器+范围for循环

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
unordered_map<int, string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
for (const auto& [key, value] : myMap) {
cout << key << ": " << value << endl;
}
}

(III)容器函数

查找最大值、最小值

  • max_element返回指向容器中最大元素的迭代器
  • min_element返回指向容器中最小元素的迭代器
  • minmax_element:返回一个pair容器,其中 first 是最小元素的迭代器,second 是最大元素的迭代器
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v={1,2,3,4,5};
auto [min_it,max_it]=minmax_element(v.begin(),v.end());
cout<<*min_it<<endl;
cout<<*max_it<<endl;
return 0;
}

⚠️ 使用*解引用迭代器
*max_element*min_element返回是元素值

判断排序

  • is_sorted判断容器是否已排序(默认升序):若满足*(i+1)>=*i时,判断已排序
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v1={1,2,3,4,5};
vector<int> v2={1,3,2,4,5};
cout<<"v1排序情况:"<<is_sorted(v1.begin(),v1.end())<<endl;
cout<<"v2排序情况:"<<is_sorted(v2.begin(),v2.end())<<endl;
return 0;
}

重载比较函数

  • is_sorted提供重载版本,可以接受自定义比较函数使用lambda expression

Leetcode 665.非递减数列

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> v={5,4,3,2,1};
bool is_descending=is_sorted(v.begin(),v.end(),[](int a,int b){return a>b;});
cout<<"v是否降序排序:"<<is_descending<<endl;
return 0;
}

(IV)最大公约数、最小公倍数

C++17 新增了 <numeric> 头文件,其中包含了 gcdlcm 函数,用于计算最大公约数和最小公倍数。

  • gcd:计算最大公约数
  • lcm:计算最小公倍数
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <numeric>
using namespace std;
int main() {
int a = 8, b = 12;
int g = gcd(a, b);
int l = lcm(a, b);
cout << g << endl;
cout << l << endl;
return 0;
}
1
2
4
24

这里考虑到CSP考试中可能只支持C++11,这里再进行一次手动实现:

最大公约数从大到小循环

1
2
3
4
5
6
7
int gcd(int a, int b) {
for (int i = min(a, b); i >= 1; i--) {
if (a % i == 0 && b % i == 0) {
return i;
}
}
return 1;

最大公约数欧几里得算法(辗转相除法)

  • 迭代实现
1
2
3
4
5
6
7
8
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
  • 递归实现
1
2
3
4
5
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}

最小公倍数

通常求得最大公约数后通过公式实现:
$$ LCM(a, b) = \frac{(a × b)}{GCD(a, b)}$$

1
2
3
int lcm(int a, int b) {
return (a / gcd(a, b)) * b;
}

map容器

  • map容器:内部有序(默认为升序)存储键值对
1
map<int,int> ans;

手动转换为降序

1
map<int,int,greater<int>> ans;

原题链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
int n=score.size();
vector<string> ans(n);
map<int,int,greater<int>> order;
for(int i=0;i<n;i++){
order[score[i]]=i;
}
auto it=order.begin();
for(int i=0;i<n;i++){
if(i==0){
ans[(*it).second]="Gold Medal";
}
else if(i==1){
ans[(*it).second]="Silver Medal";
}
else if(i==2){
ans[(*it).second]="Bronze Medal";
}
else ans[(*it).second]=to_string(i+1);
it++;
}
return ans;
}
};

排序字符串

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
string str = "badfikhfgoia";
sort(str.begin(), str.end());
cout << str << endl;
return 0;
}

判断两个字符串是否为字母异位词,效果与下面函数相同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 bool compare(string str1,string str2){
vector<int> freq(26);
for(char ch:str1){
freq[ch-'a']++;
}
for(char ch:str2){
freq[ch-'a']--;
}
for(int i=0;i<26;i++){
if(freq[i]!=0) return false;
}
return true;
}
}

<numeric>

数组求和

Leetcode 3422.统计元素和差值为偶数的分区方案

1
2
3
4
5
6
7
8
9
class Solution {
public:
int countPartitions(vector<int>& nums) {
long long sum=accumulate(nums.begin(),nums.end(),0LL);
int n=nums.size();
if(sum%2==0) return n-1;
else return 0;
}
};
1
accumulate(first,last,init,binary_op);

用于计算序列中所有元素的累积和

  • first, last:迭代器范围
  • init:初始值(必须正确指定类型)
  • binary_op:二元操作函数(可选,默认是加法)

注意使用 long long 避免溢出

1
2
vector<int> large_nums = {1000000000, 1000000000, 1000000000};
long long sum = accumulate(large_nums.begin(), large_nums.end(), 0LL);

CPP Syntax Bits and Bobs
http://example.com/2025/08/25/CPP/CPP-Syntax-Bits-and-Bobs/
Author
Li Qinxuan
Posted on
August 25, 2025
Updated on
December 5, 2025
Licensed under