一、基础语法
1、数据类型
基本数据类型:
int | 用于表示整数 | float | 用于表示单精度浮点数 | double | 用于表示双精度浮点数 | char | 用于表示字符 | bool | 用于表示布尔值,只能取 true 或 false | void | 表示无类型,通常用于函数返回类型或指针类型 |
复合数据类型:
数组 | 由相同类型的元素组成的集合 | 结构体(struct) | 由不同类型的成员组成的复合类型 | 枚举(enum) | 一组具有命名值的常量 | 类(class) | 一种封装数据和操作的方式,支持面向对象编程 | 指针(pointer) | 存储内存地址的变量,用于间接访问内存中的数据 | 引用(reference) | 提供现有变量的别名,用于简化代码和避免复制 |
引例: - int a = 10;
- cout<<sizeof(a)<<endl; //统计该变量所占内存大小
- //科学计数法
- float a = 3e2; //表示3*10^2
- float a = 3e-2; //表示3*10^-2
- //字符串
- a = 'b'
- a = "b"
- a = "hello" //单个字符时可用''或"",字符串只能用""
- //转义字符
- cout<<"hello\n"<<endl; \n为换行符
- cout<<"aa\thello"<<endl;
- cout<<"aaaa\thello"<<endl;
- cout<<"a\thello"<<endl; //\t为水平制表符,可整齐输出数据
复制代码
2、运算符
算数运算符
/可以是两个小数相除,若是两个整数相除则结果向下取整
%为取模
递增递减
++ | 前置递增 | a=2,b=++a | a=3,b=3 | ++ | 后置递增 | a=2,b=a++ | a=3,b=2 | -- | 前置递减 | a=2,b=--a | a=1,b=1 | -- | 后置递减 | a=2,b=a-- | a=1,b=2 |
所谓前置就是先加1,后置就是先运算
逻辑运算符
运算符 | 术语 | 示例 | 结果 | ! | 非 | !a | 若a为假则!a为真 | && | 与 | a&&b | 若a与b都为真则为真,否则为假 | || | 或 | a||b | 若a与b有一个为真则为真,否则为假 |
3、数组
一维数组
3种定义方式:
1)数据类型 数组名[数组长度];
2)数据类型 数组名[数组长度] = {值1,值2,……}
注意:若实际值与长度不同时,自动用0补足
3)数据类型 数组名[] = {值1,值2,……} - int arr[10];
- arr[0] = 1;
- int arr2[4] = {1,2,3,4};
- int arr3[] = {1,2,3};
复制代码
获取首地址
两种方式:arr或&arr[0]
数组长度统计 - 数组占用内存空间大小:sizeof(arr)
- 数组单个元素占用内存空间大小:sizeof(arr[0])
- 数组长度:sizeof(arr) / sizeof(arr[0])
复制代码
冒泡排序(后文具体介绍)
-
比较相邻元素: 从第一个元素开始,比较相邻的两个元素,如果它们的顺序不正确(比如在升序排序中,前一个元素大于后一个元素),则交换它们。 -
一次遍历完成: 经过一次遍历,最大(或最小)的元素会被移到序列的最后位置。 -
重复步骤1和2: 重复进行上述步骤,直到序列完全有序。在每次遍历中,待排序序列的长度减一,因为每次遍历都会将一个元素放置到了正确的位置上
二维数组
定义方式
二维数组定义的4种方式:
1)数据类型 数组名[ 行数 ][ 列数 ];
2)数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2} ,{数据3,数据4} };
3)数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
4)数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4}
注意:常用第二种,可读性较强 - int array2D[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
- cout << "Array elements:" << endl;
- for(int i = 0; i < 3; ++i) {
- for(int j = 0; j < 3; ++j) {
- cout << array2D[i][j] << " ";
- }
- cout << endl;
- }
- Array elements:
- 1 2 3
- 4 5 6
- 7 8 9
复制代码
计算行数与列数
二维数组的行数:sizeof(arr) / sizeof(arr[0])
二维数组的列数:sizeof(arr[0]) / sizeof(arr[0][0])
地址
二维数组首地址:arr[0] 或 &arr[0][0]
二维数组第1个元素的地址: arr[0] 或 &arr[0][0]
二维数组第 0 行的地址: arr或arr[0]或arr + 0
二维数组第 i 行的地址:arr或arr + i
二维数组第 i 行首元素的地址:arr或arr + i或*(arr + i)或&a[0] + i
二维数组第 i 行第 j 列元素的地址:&arr[j]或*(arr + i) + j
4、循环
for循环
- #include<bits/stdc++.h>
- using namespace std;
- int main ()
- { int sum=0;
- for (int i=1; i<=100 ; ++i)
- sum+=i;
- cout<<sum;
- return 0;
- }
复制代码
while循环
while(表达式)语句;
while(表达式){
语句1;
语句2;
}
例:用while打印数组 - #include <iostream>
- using namespace std;
- int main() {
- int array[] = {1, 2, 3, 4, 5};
- int length = sizeof(array) / sizeof(array[0]); // 计算数组的长度
- cout << "Array elements: ";
- int i = 0; // 初始化计数器
- while (i < length) {
- cout << array[i] << " ";
- i++; // 更新计数器
- }
- cout << endl;
- return 0;
- }
复制代码
do-while循环
do{
语句1;
语句2;
}
while(条件表达式)
示例:获取输入,直到输入的值为正数为止 - #include <iostream>
- using namespace std;
- int main() {
- int num;
- do {
- cout << "请输入一个正数:";
- cin >> num;
- } while (num <= 0);
- cout << "你输入的正数是:" << num << endl;
- return 0;
- }
复制代码
while和do-while的区别:
-
while 循环:
- 在 while 循环中,循环条件会在每次循环开始之前被检查。如果条件为真,循环体会执行,然后再次检查条件。如果条件为假,循环终止。
- 这意味着,如果条件一开始就为假,循环体可能一次都不会执行。
-
do-while 循环:
- 在 do-while 循环中,循环体会先执行一次,然后再检查循环条件。只要条件为真,循环体会继续执行,否则循环终止。
- 这意味着,do-while 循环至少会执行一次循环体,即使条件一开始就为假。
嵌套循环
示例:水仙花数字 - #include<bits/stdc++.h>
- using namespace std;
- int main()
- { for (int a=1; a<=9; ++a)
- for (int b=0; b<=9; ++b)
- for (int c=0; c<=9; ++c)
- { if (a*a*a+b*b*b+c*c*c==a*100+b*10+c)
- cout<<setw(6)<<a*100+b*10+c; //setw函数控制输出场宽
- }
- return 0;
- }
复制代码
5、条件语句(if)
单行格式if - #include <iostream>
- using namespace std;
- int main() {
- int num;
- cout << "请输入一个整数:";
- cin >> num;
- if (num > 0) {
- cout << "这是一个正数。" << endl;
- }
- return 0;
- }
复制代码
多行格式if - #include <iostream>
- using namespace std;
- int main() {
- int num;
- cout << "请输入一个整数:";
- cin >> num;
- if (num > 0) {
- cout << "这是一个正数" << endl;
- }
- else if (num == 0){
- cout << "0" << endl;
- }
- else{
- cout << "这是一个负数" << endl;
- }
- return 0;
- }
复制代码
6、结构体
语法
结构体创建变量 - #include <iostream>
- using namespace std;
- // 定义一个名为 Person 的结构体
- struct Person {
- string name;
- int age;
- double height;
- };
- int main() {
- // 创建一个 Person 类型的对象
- struct Person person1;
- // 给结构体成员赋值
- person1.name = "Alice";
- person1.age = 30;
- person1.height = 5.6;
- // 输出结构体成员的值
- cout << "Name: " << person1.name << endl;
- cout << "Age: " << person1.age << endl;
- cout << "Height: " << person1.height << endl;
-
- struct Person person2 = {"BEN",40,4.4};
- return 0;
- }
复制代码
结构体数组 - #include <iostream>
- #include <string>
- using namespace std;
- // 定义一个名为 Person 的结构体
- struct Person {
- string name;
- int age;
- double height;
- };
- int main() {
- // 使用大括号初始化结构体数组
- Person people[3] = {
- {"Alice", 30, 5.6},
- {"Bob", 25, 6.0},
- {"Charlie", 35, 5.9}
- };
- // 输出结构体数组中每个结构体的成员值
- for (int i = 0; i < 3; ++i) {
- cout << "Person " << i+1 << ":" << endl;
- cout << "Name: " << people[i].name << endl;
- cout << "Age: " << people[i].age << endl;
- cout << "Height: " << people[i].height << endl;
- cout << endl;
- }
- return 0;
- }
复制代码
结构体指针 - #include <iostream>
- using namespace std;
- // 定义一个名为 Person 的结构体
- struct Person {
- string name;
- int age;
- double height;
- };
- int main() {
- // 创建一个 Person 类型的结构体指针
- struct Person* p = new Person;
- // 使用 -> 运算符给结构体成员赋值
- p->name = "Alice";
- p->age = 30;
- p->height = 5.6;
- // 使用 -> 运算符访问结构体成员并输出
- cout << "Name: " << p->name << endl;
- cout << "Age: " << p->age << endl;
- cout << "Height: " << p->height << endl;
- // 记得释放动态分配的内存
- delete p;
- return 0;
- }
复制代码
结构体嵌套
结构体中成员是另一个结构体
7、函数
主函数为main(),但可以创作其他函数进行运算,只需在主函数中调用即可,以下以阶乘为例 - #include <iostream>
- using namespace std;
- int factorial(int n){
- if(n==1)
- return n;
- else
- return n*factorial(n-1);
- }
- int main()
- {
- int n;
- cout << "请输入整数:" << endl;
- cin >> n;
- cout << "整数:" << n << "的阶乘为:" << factorial(n) << endl;
- cout << "\n" << endl;
- return 0;
- }
复制代码
二、STL库
STL(Standard Template Library)是 C++ 标准库的一部分,它提供了一组通用的模板类和函数,用于实现常见的数据结构和算法。STL 的设计旨在提供一种高效、灵活和可重用的方法来处理数据结构和算法问题。总的来说,STL库装了许多算法和组件,包含多种函数,可用于开发各类应用程序
1、快速排序(Sort)
基本用法
格式: - void sort(起始地址,结束地址,比较函数);
复制代码- #include<algorithm>
- #include<iostream>
- using namespace std;
- int main(){
- int a[] = {2,3,5,4,1,8,6,9};
- sort(a,a+8);//a为数组的开头,a+8就等于排序到数组的第8个元素
- for(int i=0;i<6;i++)
- cout<<a[i]<<" ";
-
- }
复制代码
cmp用法
在sort比较函数中传入排序函数,>为降序,<为升序 - #include<algorithm>
- #include<iostream>
- using namespace std;
- bool cmp(int x,int y)
- {
- if(x>y)return true;//降序
- return false;
- }
- int main(){
- int a[] = {2,3,5,4,1,8,6,9};
- sort(a,a+8,cmp);//a为数组的开头,a+8就等于排序到数组的第8个元素
- for(int i=0;i<6;i++)
- cout<<a[i]<<" ";
-
- }
复制代码
2、关联容器(Map)
map是一个关联容器,它提供了一种将键与值关联起来的方式,map中的每个元素都是一个键(key-value pair),其中键(key)是唯一的,值(value)则可以不唯一。它基于红黑树(Red-Black Tree)实现。
注意:map不允许容器中有重复的key值,multimap允许容器中有重复的key
格式: - #include <iostream>
- #include <map>
- int main() {
- map<string, int> phonebook;
- phonebook["Alice"] = 123456;
- phonebook["Bob"] = 789012;
- phonebook["Charlie"] = 345678;
- cout << "Bob's phone number: " << phonebook["Bob"] << endl;
- phonebook["Alice"] = 111111;
- phonebook.erase("Charlie");
- // 遍历元素
- for (const auto& pair : phonebook) {
- cout << pair.first << "'s phone number: " << pair.second <<endl;
- }
- return 0;
- }
复制代码
1)构造
map mp; | map对象默认构造形式 | map(const map &qmp); | 拷贝构造函数 |
2)赋值
map& operator=(const map &mp); | 重载等号操作符 |
3)大小和交换
size(); | 返回容器中元素数目 | empty(); | 判断容器是否为空 | swap(st); | 交换两个集合容器 |
4)插入和删除
insert(elem); | 在容器中插入元素 | clear(); | 清除所有元素 | erase(pos); | 删除pos迭代器所指的元素,返回下一个元素的选代器 | erase(beg,end); | 删除区间[beg,end)的所有元素,返回下一个元素的迭代器 | erase(elem); | 删除容器中值为elem的元素。 |
5)查找和统计
find(key); | 查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end() | count(key); | 统计key的元素的个数 |
3、栈(stack)
相当于是一个小箱子,每次向箱子顶部塞入数据,遵循先进后出(Last In, First Out,LIFO)的原则。栈可以被看作是一种容器,其中元素按照后进先出的顺序进行插入和删除。
格式: - #include<stack>
- stack<数据类型>一个自定义的名字;
- 或:
- stack 一个自定义的名字;
复制代码
栈的成员函数
.empty() | 判断栈是否为空,空则返回true | .push(…) | 在栈顶增加元素 | .pop() | 在栈顶移除元素 | .top() | 返回栈顶元素 | .size() | 返回栈的元素数量 |
代码示例: - #include<stack>
- #include<iostream>
- using namespace std;
- stack<int> st;
- int main(){
-
- st.push(1);
- st.push(2);
- st.push(3);
- cout<<st.top();
- return 0;
- }
- 输出:
- 3
复制代码
4、动态数组容器(Vector)
使用的时候可以看作数组,但他相对于数组来说可以动态扩展,增加长度
1)构造 - 头文件:#include<vector>
- 构造:vector<T> v ;
- 放入数据:v.push_back(…);
- 迭代器:vector<int>::iterator
- 将[v.begin(),v.end())区间中的元素拷贝给本身:vector(v.begin(),v.end());
- 将n个elem拷贝给本身:vextor(n,elem);
- 拷贝构造函数:vector(const vector &v) ;
复制代码- void printVector(vector<int>& v)
- { //利用迭代器打印 v
- for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
- {
- cout << *it << " ";
- }
- cout << endl;
- }
- void text01()
- {
- vector<int> v1;
- for (int i = 0; i < 5; ++i)
- {
- v1.push_back(i);//向v1末尾添加数据
- }
- vector<int> v2(v1.begin(), v1.end()); //构造2
- vector<int> v3(5, 5); //构造3
- vector<int> v4(v3); //构造4
-
- cout << "打印v2: ";
- printVector(v2);
- cout << "打印v3: ";
- printVector(v3);
- cout << "打印v4: ";
- printVector(v4);
- }
复制代码
2)遍历
v.begin() | 返回迭代器,这个迭代器指向容器中第一个数据 | v.end() | 返回迭代器,这个迭代器指向容器元素的最后元素的下一个位置 | vector::iterator | 拿到这种容器的迭代器类型 |
第一种遍历方式 - vector<int>::iterator pBegin = v.begin();
- vector<int>::iterator pEnd = v.end();
- while(pBegin != pEnd){
- cout<<*pBegin<<endl;
- pBegin++;
- }
复制代码
第二种遍历方式 - for (vector<int>::iterator it = v.begin();it != v.end();it++){
- cout<<*it<<endl;
- }
复制代码
3)赋值
vector& operator=(const vector &v); | 重载赋值运算符 | assign(v.begin(),v.end()); | 将[v.begin(),v.end())区间中的元素赋值给本身 | assign(n,elem); | 将n个elem赋值给本身 | - void printVector(vector<int>& v)
- { //利用迭代器打印 v
- for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
- {
- cout << *it << " ";
- }
- cout << endl;
- }
- void text02()
- {
- vector<int> v1,v2;
- for (int i = 0; i < 5; ++i)
- {
- v1.push_back(i);
- }
- v2 = v1;
- vector<int> v3,v4;
- v3.assign(v1.begin(), v1.end());
- v4.assign(10,100);
- cout << "打印v2: ";
- printVector(v2);
- cout << "打印v3: ";
- printVector(v3);
- cout << "打印v4: ";
- printVector(v4);
- }
复制代码
4)容量和大小
empty(); | 判断容器是否为空 | capacity(); | 容器容量 | size(); | 容器中元素个数 | resize(int num); | 重新指定长度num,变短删末尾元素,变长以默认值填充新位置 | resize(int num,elem); | 重新指定长度num,变短删末尾元素,变长以elem填充新位置 |
5)插入和删除
push_back(elem); | 尾部插入元素elem | pop_back(); | 删除最后一个元素 | insert(const_iterator pos,elem); | 指向的位置pos处插入一个元素elem | insert(const_iterator pos,int count,elem); | 指向的位置pos处count元素elem | erase(const_iterator pos); | 指向的位置pos处删除元素 | erase(const_iterator start,const_iterator end); | 删除start到end之间的元素 | clear(); | 清空所有元素 |
6)数据存取
at(int id); | 返回id处数据 | operator[]; | 返回[]处数据 | front(); | 返回第一个数据 | back(); | 返回最后一个数据 |
7)互换容器
8)预留空间
reserve(int len); | 预留len个元素长度 |
当数据量较大时可以一开始就利用reserve预留空间
5、String
string内部封装了许多成员方法,如find,copy,delete,insert,replace等
头文件:#include
1)构造
string(); | 构造空字符串 | string(const char* s); | 拷贝s所指向的字符串序列,使字符串s初始化 | string(const char* s, size_t n); | 拷贝s所指向的字符串序列的第n个到结尾的字符 | string(size_t n, char c); | 将字符c复制n次 | string(const string& str); | 拷贝构造函数。使用一个string对象初始化另一个对象 | string(const string& str, size_t pos, size_t n = npos); | 拷贝s中从pos位置起的n个字符,若npos>字符串长度,就拷贝到字符串结尾结束 | - #include<string>
- void test1(){
- string s1; //创建空字符串,使用无参构造函数
-
- const char*str = "hello";
- string s2(str);
- string s3(s2); //调用拷贝构造函数
- string s4(10,'a'); //将字符a复制10次
- string s5(s2,1);//拷贝s2所指向的字符串序列的第1个到结尾的字符
- }
复制代码
2)赋值
string& operator=(const char* s); | char*类型字符串赋值给当前的字符串 | string& operator=(const string &s); | 把字符串s赋给当前的字符串 | string& operator=(char c); | 字符赋值给当前的字符串 | string& assign(const char *s); | 把字符串s赋给当前的字符串 | string& assign(const char *s, int n); | 把字符串s的前n个字符赋给当前的字符串 | string& assign(const string &s); | 把字符串s赋给当前字符串 | string& assign(int n, char c); | 用n个字符c赋给当前字符串 |
3)字符串插入、拼接和删除
插入:
void push_back (char c); | 向字符串末尾追加一个字符 | string& insert(size_t pos, const string& str); | 插入字符串拷贝 | string& insert (size_t pos, const char* s); | 插入c形式的字符串 | string& insert (size_t pos, const char* s, size_t n); | 将字符串s的前n个字符插到pos位置 | - #include<iostream>
- #include<string>
- using namespace std;
- int main()
- {
- string s0("");
- s0.push_back('a');//s0尾插入a
-
- string s1("b");
- s0.insert(1, s1);//在下标为1的位置插入s1的拷贝
-
- s0.insert(4, "c");//在下标为4的位置插入字符串o
- s0.insert(0, "hello",2);//在下标为0的位置插入"hello"的前2个字符
-
- return 0;
- }
复制代码
拼接:
string& operator+=(const char* str); | 重载+=操作符 | string& operator+=(const char c); | 重载+=操作符 | string& operator+=(const string& str); | 重载+=操作符 | string& append(const char *s); | 把字符串s连接到当前字符串结尾 | string& append(const char *s, int n); | 把字符串s的前n个字符连接到当前字符串结尾 | string& append(const string &s); | 同operator+"(const string& str) | string& append(const string &s,int pos,int n); | 字符用s中从pos开始的n个字符连接到字符串结尾 |
删除:
string& erase(int pos, int n = npos); | 删除从pos开始的第n个字符 | - str.erase(1,3); //从1号位置开始删除3个字符
复制代码
4)查找和替换
int find(const string& str, int pos = 0) const; | 查找str最后一次位置,从pos开始查找 | int find(const char*s, int pos =0)const; | 查线s第一次出现位置,从pos开始查找 | int find(const char* s, int pos, int n) const; | 从pos位置查找s的前n个字符第一次位置 | int find(const char c, int pos=0) const; | 查找字符c第一次出现位置 | int rfind(const string& str, int pos = npos) const; | 查找str最后一次位置,从pos开始查找 | int rfind(const char* s, int pos = npos) const; | 查找s最后一次出现位置.从pos开始查找 | int rfind(const char* s, int pos, int n) const; | 从pos查找s的前n个字符最后一次位置 | int rfind(const char c, int pos = 0) const; | 查找李符c最后一次出现位置 | string& replace(int pos, int n, const string& str); | 替换从pos开始n个字符为字符串str | string& replace(int pos, int n, const char* s); | 替换从pos开始的n个字符为字符串s |
注意:
find是从左往右查找,rfind是从右往左查找
find找到字符串后返回查找的第一个字符位置,找不到就返回-1
replace在替换时,要指定从哪个位置起,替换多少个字符,替换成什么
5)字符串的比较
int compare(const string &s) const; | 与字符串s比较 | int compare(const char *s) const: | 与字符串s比较 |
注意:若=则返回0,>返回1,<返回-1 - int main(){
- string s1="hello";
- string s2="hhllo";
- int ret = s1.compare(s2);
-
- ……
- return 0;
- }
复制代码
6)字符串存取
char& operator[](int n); | 通过[]方式取字符 | char& at(int n); | 通过at方式取字符 | - int main(){
- string str = "hello world"
- for (int i = 0;i < str.size();i++){
- cout << str[i] << " ";
- cout << str.at(i) << " ";
- }
- cout<<endl;
- }
- //字符修改:
- str[0] = "x";
- str.at(1) = "x";
- return 0;
- }
复制代码
7)子串
string substr(int pos=0,int n = npos) const; | 返回由pos开始的n个字符组成的字符串 | - void teste1(){
- string str ="abcdefg";
- string substr = str.substr(1,3)
- cout<<"substr ="<< substr << endl;
- string email="hello@sina.com";
- int pos = email.find("@");
- string username =email.substr(0, pos);
- cout<<"username:"<<username<< endl
- }
- int main(){
- teste1();
- system("pause");
- return0;
- }
复制代码
6、Set
基本概念:以有序的方式存储一组唯一的元素。具体来说,std::set使用红黑树(Red-Black Tree)实现,这使得元素在插入时就会按照特定的顺序进行排序,并且保证了查找、插入和删除操作的高效性能。
注意:set不允许容器出现重复元素,multiset允许容器出现重复元素
头文件:#include
遍历: - #include <set>
- void printSet(set<int> &s){
- for(set<int>::iterator it=s.begin();it!=s.end;it++){
- cout<<*it<<" ";
- }
- cout<<endl;
- }
复制代码
1)构造和赋值
set st; | 默认构造函数 | set(sonst set &st); | 拷贝构造函数 | set& operator=(const set &st); | 重载等号操作符 | - set<int> s1;
- s1.insert(10);
- s1.insert(10);
- set<int>s2(s1); //拷贝构造
- set<int> s3;
- s3=s2; //赋值
复制代码
2)大小和交换
size(); | 返回容器中元素数目 | empty(); | 判断容器是否为空 | swap(st); | 交换两个集合容器 | - set<int> s1;
- s1.insert(10);
- s1.insert(20);
- s1.insert(30);
- set<int> s2;
- s1.insert(40);
- s1.insert(50);
- s1.insert(60);
- s1.swap(s2);
复制代码
3)插入和删除
insert(elem); | 在容器中插入元素 | clear(); | 清除所有元素 | erase(pos); | 删除pos迭代器所指的元素,返回下一个元素的选代器 | erase(beg,end); | 删除区间[beg,end)的所有元素,返回下一个元素的迭代器 | erase(elem); | 删除容器中值为elem的元素。 | - set<int> s1;
- s1.insert(10);
- s1.insert(20);
- s1.insert(30);
- s1.erase(s1.begin()); //删除
- s1.erase(10);
- s1.clear(); //清空
复制代码
4)查找和统计
find(key); | 查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end() | count(key); | 统计key的元素的个数 |
7、Queue
先进先出的数据结果,有两个出口,只有队头和队尾能被外界访问,因此不存在遍历的行为
1)构造函数
queue que; | queue对象默认构造形式 | queue(const queue &que); | 拷贝构造函数 |
2)赋值
queue& operator=(const queue &que); | 重载等号操作符 |
3)数据存取
push(elem); | 往队尾添加元素 | pop(); | 从队头移除一个元素 | back(); | 返回最后一个元素 | front(); | 返回第一个元素 |
4)大小
empty(); | 判断堆栈是否为空 | size(); | 返回栈的大小 |
三、字符串
1、简介
C语言风格: - char a[5] = {'1','2','3','4','5'}; //字符数组
- char b[5] = {'1','2','3','4','\0'}; //字符串
- char greeting['h','e','l','l','o','\0'}; //字符串
- char greeting[]="hello";
- //输出结果为 hello
复制代码
C++引入的string类类型(函数及其目的)
Strcpy(s1,s2) | 复制字符串s2到字符串s1 | Strcat(s1,s2) | 连接字符串s2到s1的末尾 | Strlen(s1) | 返回字符串s1的长度 | Strcmp(s1,s2) | 若s1=s2,返回0 若s1 若s1>s2,返回值大于0 | Strchr(s1,s2) | 返回一个指针,指向s1中字符ch第一次出现的位置 | Strstr(s1,s2) | 返回一个指针,指向s1中s2第一次出现的位置 |
2、字符串的读入
1)对字符数组得输入方法
1.1cin使用空白字符作为一次输入的结尾,并忽略该空字 - char word[10];
- cin >> word;
- cout<<word;
- //若输入123 456,只会输出123
复制代码
该情况下只能输入一个单词,若输入了多个单词,只会取第一个单词,其余单词被忽略掉
1.2使用getline()/get()函数完成面向行的输入
区别:主要区别在于它们处理输入流的方式:getline() 用于读取整行并丢弃定界符,而 get() 则用于逐字符读取,并保留定界符在输入流中。
#cin.getline() - cin.getline(line,nums,(optional)delim)
复制代码
nums:代表从该队列中获取nums-1个字符到line中(最后一个字符为\0)若超出nums-1,后面的都无法取到。
delim:指定分界符,表示遇到分界符后当前字符串的输入将停止,其后的会保留在输入队列中作为下一个字符串的开始。 - int main(){
- char line1[10];
- char line2[10];
- cin.getline(line1,10,'s');
- cin.getline(line2,10);
- cout<<line1<<endl;
- cout<<line2<<endl;
- return 0;
- }
- //测试:123s456
- //结果:
- line1:123
- line2:456
复制代码
#cin.get() - cin.get(line,nums,(optional)delim)
复制代码
get会在输入队列中保留最后的换行符,若不做处理可能出现问题,以下方式可以避免: - cin.get(line2,10).get();
- cin.get(line2,10);
- get();
复制代码
1.3数字与字符串混合输入 - int a,b;
- char s[7];
- cin>>a;
- (cin>>b).get();
- cin.getline(s,7);
- cout<<a<<" "<<b<<" "<<s;
- //测试:123 456 hello
- 结果:
- 123
- 456
- hello
- 123 456 hello
复制代码
2)对string对象的输入方法 - string a
- getline(cin,a);
- cout<<a<<endl;
复制代码
3、常见操作
1)常用函数
2)读写string - string s1,s2,s3;
- cin>>s1;
- cin>>s2>>s3;
- //结果:
- nice to meet
- nice
- to
- meet
复制代码
若要保留输入时的空格,可以使用getline - string s1;
- getline(cin,s1);
- //结果:
- nice to meet
- nice to meet
复制代码
3)cctype头文件
4)用for循环完成cctype各项 - #include<iostream>
- #include<string>
- #include<cctype>
- using namespace std;
- int main(void){
- string s1 = "hello world";
- for(auto &c : s1)
- c=toupper(c);
- cout<<s1<<endl;
- return 0;
- }
- //结果
- HELLO WORLD
复制代码
四、排序
1、冒泡排序
原理:比较前后两个数字的大小,大的放在后面,依次遍历所有数字 - #include <iostream>
- #define N 1010
- using namespace std;
-
- int n = 6; //待排序的元素个数为6
- int a[N] = {0,2,3,2,11,7,6}; //待排序元素
-
- int main(){
-
- for(int i = 1;i<n;i++){ //连续交换过程
- //一共n-1个阶段,在第i个阶段,未排序序列长度从n-i+1到n-i
-
- for (int j = 1;j<=n-i;++j) //将序列从1到n-i+1的最大值移到n-i+1的位置
- if (a[j] > a[j+1]) // 将序列从1到n-i+1的最大值,移到n-i+1的位置
- swap(a[j],a[j+1]); // 其中j枚举的是前后交换元素的前一个元素序号
- }
-
- //输出
- for (int i=1;i<=n;++i)
- cout<<a[i]<<' ';
- cout<<endl;
- return 0;
- }
复制代码
2、选择排序
原理:
- 遍历数组,找到最小(或最大)的元素。
- 将找到的最小(或最大)元素与数组的第一个元素交换位置。
- 排除第一个元素,对剩余的元素进行相同的操作,即在剩余的未排序部分中找到最小(或最大)的元素,并与该部分的第一个元素交换位置。
- 重复以上步骤,直到整个数组排序完成。
缺点:平均时间复杂度为O(n^2),空间复杂度为O(1),性能通常比较差。 - #include <iostream>
- #include <vector>
- using namespace std;
- // 选择排序函数
- void selectionSort(vector<int>& arr) {
- int n = arr.size();
-
-
- for (int i = 0; i < n - 1; ++i) { // 外层循环遍历数组
-
- int minIndex = i; // 假设当前元素为最小值的索引
-
- // 内层循环寻找最小值的索引
- for (int j = i + 1; j < n; ++j) {
-
- if (arr[j] < arr[minIndex]) { // 如果找到更小的元素,则更新最小值的索引
- minIndex = j;
- }
- }
-
-
- swap(arr[i], arr[minIndex]); // 将最小值与当前位置的元素交换位置
- }
- }
- int main() {
- // 测试选择排序函数
- vector<int> arr = {64, 25, 12, 22, 11};
-
- cout << "Original array: ";
- for (int num : arr) {
- cout << num << " ";
- }
- cout << endl;
-
-
- selectionSort(arr); // 调用选择排序函数
-
- cout << "Sorted array: ";
- for (int num : arr) {
- cout << num << " ";
- }
- cout << endl;
-
- return 0;
- }
复制代码
3、插入排序
原理:
- 将数组视为两部分,一部分是已排序的部分,一部分是未排序的部分。
- 从未排序部分取出第一个元素,在已排序部分中从后往前逐个比较,找到合适的位置插入该元素,使得插入后的部分仍然保持有序。
- 重复上述过程,直到未排序部分为空,整个数组就排好序了。
优点:适合小型数据集或部分有序的数据。 - #include<iostream>
- using namespace std;
-
- int main() {
- int a[6] = { 2, 6, 5, 3, 4, 1}; // 待排序序列
- int temp, i, j;
- int n = 6; // 待排序元素个数
-
- // 开始插入排序
- for (i = 1; i < 6; i++) {
- // 假定第一个数是有序的,从第二个数开始枚举
- temp = a[i]; // 临时储存每一次需要排序的数
- j = i; // j用于记录当前待排序元素的位置
- // 在有序部分从后往前比较,将比当前元素大的元素往后移动
- while (j >= 1 && temp < a[j - 1]) {
- a[j] = a[j - 1]; // 元素往后移动
- j--; // 继续向前搜索
- }
- a[j] = temp; // 将待排序元素插入到合适的位置
- }
-
- // 输出排序后的结果
- for (i = 0; i < 6; i++) {
- cout << a[i] << " ";
- }
- cout << endl;
- return 0;
- }
复制代码
|