当前位置:   article > 正文

C++全系列学习(基础篇)_c++学习

c++学习

一、基础语法

1、数据类型

基本数据类型:

int用于表示整数
float用于表示单精度浮点数
double用于表示双精度浮点数
char用于表示字符
bool用于表示布尔值,只能取 truefalse
void表示无类型,通常用于函数返回类型或指针类型

复合数据类型:

数组由相同类型的元素组成的集合
结构体(struct由不同类型的成员组成的复合类型
枚举(enum一组具有命名值的常量
类(class一种封装数据和操作的方式,支持面向对象编程
指针(pointer存储内存地址的变量,用于间接访问内存中的数据
引用(reference提供现有变量的别名,用于简化代码和避免复制

引例:

  1. int a = 10;
  2. cout<<sizeof(a)<<endl; //统计该变量所占内存大小
  3. //科学计数法
  4. float a = 3e2; //表示3*10^2
  5. float a = 3e-2; //表示3*10^-2
  6. //字符串
  7. a = 'b'
  8. a = "b"
  9. a = "hello" //单个字符时可用''或"",字符串只能用""
  10. //转义字符
  11. cout<<"hello\n"<<endl; \n为换行符
  12. cout<<"aa\thello"<<endl;
  13. cout<<"aaaa\thello"<<endl;
  14. cout<<"a\thello"<<endl; //\t为水平制表符,可整齐输出数据

2、运算符

算数运算符

/可以是两个小数相除,若是两个整数相除则结果向下取整

%为取模

递增递减

++前置递增a=2,b=++aa=3,b=3
++后置递增a=2,b=a++a=3,b=2
--前置递减a=2,b=--aa=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,……}

  1. int arr[10];
  2. arr[0] = 1;
  3. int arr2[4] = {1,2,3,4};
  4. int arr3[] = {1,2,3};
获取首地址

两种方式:arr或&arr[0]

数组长度统计
  1. 数组占用内存空间大小:sizeof(arr)
  2. 数组单个元素占用内存空间大小:sizeof(arr[0])
  3. 数组长度:sizeof(arr) / sizeof(arr[0])
冒泡排序(后文具体介绍)
  1. 比较相邻元素: 从第一个元素开始,比较相邻的两个元素,如果它们的顺序不正确(比如在升序排序中,前一个元素大于后一个元素),则交换它们。

  2. 一次遍历完成: 经过一次遍历,最大(或最小)的元素会被移到序列的最后位置。

  3. 重复步骤1和2: 重复进行上述步骤,直到序列完全有序。在每次遍历中,待排序序列的长度减一,因为每次遍历都会将一个元素放置到了正确的位置上

二维数组

定义方式

二维数组定义的4种方式:

1)数据类型 数组名[ 行数 ][ 列数 ];

2)数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2} ,{数据3,数据4} };

3)数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};

4)数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4}

注意:常用第二种,可读性较强

  1. int array2D[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
  2. cout << "Array elements:" << endl;
  3. for(int i = 0; i < 3; ++i) {
  4. for(int j = 0; j < 3; ++j) {
  5. cout << array2D[i][j] << " ";
  6. }
  7. cout << endl;
  8. }
  9. Array elements:
  10. 1 2 3
  11. 4 5 6
  12. 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 行的地址: arrarr[0]arr + 0 

二维数组第 i 行的地址:arr[i]arr + i

二维数组第 i 行首元素的地址:arr[i]arr + i*(arr + i)&a[0] + i

二维数组第 i 行第 j 列元素的地址:&arr[i][j]*(arr + i) + j

4、循环

for循环

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main ()
  4. { int sum=0;
  5. for (int i=1; i<=100 ; ++i)
  6. sum+=i;
  7. cout<<sum;
  8. return 0;
  9. }

while循环

while(表达式)语句;

while(表达式){

    语句1;

    语句2;

}

例:用while打印数组

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int array[] = {1, 2, 3, 4, 5};
  5. int length = sizeof(array) / sizeof(array[0]); // 计算数组的长度
  6. cout << "Array elements: ";
  7. int i = 0; // 初始化计数器
  8. while (i < length) {
  9. cout << array[i] << " ";
  10. i++; // 更新计数器
  11. }
  12. cout << endl;
  13. return 0;
  14. }

do-while循环

do{

    语句1;

    语句2;

}

while(条件表达式)

示例:获取输入,直到输入的值为正数为止

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int num;
  5. do {
  6. cout << "请输入一个正数:";
  7. cin >> num;
  8. } while (num <= 0);
  9. cout << "你输入的正数是:" << num << endl;
  10. return 0;
  11. }

while和do-while的区别

  1. while 循环

    • while 循环中,循环条件会在每次循环开始之前被检查。如果条件为真,循环体会执行,然后再次检查条件。如果条件为假,循环终止。
    • 这意味着,如果条件一开始就为假,循环体可能一次都不会执行。
  2. do-while 循环

    • do-while 循环中,循环体会先执行一次,然后再检查循环条件。只要条件为真,循环体会继续执行,否则循环终止。
    • 这意味着,do-while 循环至少会执行一次循环体,即使条件一开始就为假。

嵌套循环

示例:水仙花数字

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main()
  4. { for (int a=1; a<=9; ++a)
  5. for (int b=0; b<=9; ++b)
  6. for (int c=0; c<=9; ++c)
  7. { if (a*a*a+b*b*b+c*c*c==a*100+b*10+c)
  8. cout<<setw(6)<<a*100+b*10+c; //setw函数控制输出场宽
  9. }
  10. return 0;
  11. }

5、条件语句(if)

单行格式if

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int num;
  5. cout << "请输入一个整数:";
  6. cin >> num;
  7. if (num > 0) {
  8. cout << "这是一个正数。" << endl;
  9. }
  10. return 0;
  11. }

多行格式if

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int num;
  5. cout << "请输入一个整数:";
  6. cin >> num;
  7. if (num > 0) {
  8. cout << "这是一个正数" << endl;
  9. }
  10. else if (num == 0){
  11. cout << "0" << endl;
  12. }
  13. else{
  14. cout << "这是一个负数" << endl;
  15. }
  16. return 0;
  17. }

6、结构体

语法

struct 结构体名 { 结构体成员列表 };

结构体创建变量

  1. #include <iostream>
  2. using namespace std;
  3. // 定义一个名为 Person 的结构体
  4. struct Person {
  5. string name;
  6. int age;
  7. double height;
  8. };
  9. int main() {
  10. // 创建一个 Person 类型的对象
  11. struct Person person1;
  12. // 给结构体成员赋值
  13. person1.name = "Alice";
  14. person1.age = 30;
  15. person1.height = 5.6;
  16. // 输出结构体成员的值
  17. cout << "Name: " << person1.name << endl;
  18. cout << "Age: " << person1.age << endl;
  19. cout << "Height: " << person1.height << endl;
  20. struct Person person2 = {"BEN",40,4.4};
  21. return 0;
  22. }

结构体数组

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. // 定义一个名为 Person 的结构体
  5. struct Person {
  6. string name;
  7. int age;
  8. double height;
  9. };
  10. int main() {
  11. // 使用大括号初始化结构体数组
  12. Person people[3] = {
  13. {"Alice", 30, 5.6},
  14. {"Bob", 25, 6.0},
  15. {"Charlie", 35, 5.9}
  16. };
  17. // 输出结构体数组中每个结构体的成员值
  18. for (int i = 0; i < 3; ++i) {
  19. cout << "Person " << i+1 << ":" << endl;
  20. cout << "Name: " << people[i].name << endl;
  21. cout << "Age: " << people[i].age << endl;
  22. cout << "Height: " << people[i].height << endl;
  23. cout << endl;
  24. }
  25. return 0;
  26. }

结构体指针

  1. #include <iostream>
  2. using namespace std;
  3. // 定义一个名为 Person 的结构体
  4. struct Person {
  5. string name;
  6. int age;
  7. double height;
  8. };
  9. int main() {
  10. // 创建一个 Person 类型的结构体指针
  11. struct Person* p = new Person;
  12. // 使用 -> 运算符给结构体成员赋值
  13. p->name = "Alice";
  14. p->age = 30;
  15. p->height = 5.6;
  16. // 使用 -> 运算符访问结构体成员并输出
  17. cout << "Name: " << p->name << endl;
  18. cout << "Age: " << p->age << endl;
  19. cout << "Height: " << p->height << endl;
  20. // 记得释放动态分配的内存
  21. delete p;
  22. return 0;
  23. }

结构体嵌套

结构体中成员是另一个结构体

7、函数

主函数为main(),但可以创作其他函数进行运算,只需在主函数中调用即可,以下以阶乘为例

  1. #include <iostream>
  2. using namespace std;
  3. int factorial(int n){
  4. if(n==1)
  5. return n;
  6. else
  7. return n*factorial(n-1);
  8. }
  9. int main()
  10. {
  11. int n;
  12. cout << "请输入整数:" << endl;
  13. cin >> n;
  14. cout << "整数:" << n << "的阶乘为:" << factorial(n) << endl;
  15. cout << "\n" << endl;
  16. return 0;
  17. }

二、STL库

STL(Standard Template Library)是 C++ 标准库的一部分,它提供了一组通用的模板类和函数,用于实现常见的数据结构和算法。STL 的设计旨在提供一种高效、灵活和可重用的方法来处理数据结构和算法问题。总的来说,STL库装了许多算法和组件,包含多种函数,可用于开发各类应用程序

1、快速排序(Sort)

基本用法

格式:

void sort(起始地址,结束地址,比较函数);
  1. #include<algorithm>
  2. #include<iostream>
  3. using namespace std;
  4. int main(){
  5. int a[] = {2,3,5,4,1,8,6,9};
  6. sort(a,a+8);//a为数组的开头,a+8就等于排序到数组的第8个元素
  7. for(int i=0;i<6;i++)
  8. cout<<a[i]<<" ";
  9. }

cmp用法

在sort比较函数中传入排序函数,>为降序,<为升序

  1. #include<algorithm>
  2. #include<iostream>
  3. using namespace std;
  4. bool cmp(int x,int y)
  5. {
  6. if(x>y)return true;//降序
  7. return false;
  8. }
  9. int main(){
  10. int a[] = {2,3,5,4,1,8,6,9};
  11. sort(a,a+8,cmp);//a为数组的开头,a+8就等于排序到数组的第8个元素
  12. for(int i=0;i<6;i++)
  13. cout<<a[i]<<" ";
  14. }

2、关联容器(Map)

map是一个关联容器,它提供了一种将键与值关联起来的方式,map中的每个元素都是一个键(key-value pair),其中键(key)是唯一的,值(value)则可以不唯一。它基于红黑树(Red-Black Tree)实现。

注意:map不允许容器中有重复的key值,multimap允许容器中有重复的key

格式:

map(数据类型,数据类型)一个自定义的名称;
  1. #include <iostream>
  2. #include <map>
  3. int main() {
  4. map<string, int> phonebook;
  5. phonebook["Alice"] = 123456;
  6. phonebook["Bob"] = 789012;
  7. phonebook["Charlie"] = 345678;
  8. cout << "Bob's phone number: " << phonebook["Bob"] << endl;
  9. phonebook["Alice"] = 111111;
  10. phonebook.erase("Charlie");
  11. // 遍历元素
  12. for (const auto& pair : phonebook) {
  13. cout << pair.first << "'s phone number: " << pair.second <<endl;
  14. }
  15. return 0;
  16. }

1)构造

map<T1,T2> 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)的原则。栈可以被看作是一种容器,其中元素按照后进先出的顺序进行插入和删除。

格式:

  1. #include<stack>
  2. stack<数据类型>一个自定义的名字;
  3. 或:
  4. stack 一个自定义的名字;

栈的成员函数

.empty()判断栈是否为空,空则返回true
.push(…)在栈顶增加元素
.pop()在栈顶移除元素
.top()返回栈顶元素
.size()返回栈的元素数量

代码示例:

  1. #include<stack>
  2. #include<iostream>
  3. using namespace std;
  4. stack<int> st;
  5. int main(){
  6. st.push(1);
  7. st.push(2);
  8. st.push(3);
  9. cout<<st.top();
  10. return 0;
  11. }
  12. 输出:
  13. 3

4、动态数组容器(Vector)

使用的时候可以看作数组,但他相对于数组来说可以动态扩展,增加长度

1)构造

  1. 头文件:#include<vector>
  2. 构造:vector<T> v ;
  3. 放入数据:v.push_back(…);
  4. 迭代器:vector<int>::iterator
  5. 将[v.begin(),v.end())区间中的元素拷贝给本身:vector(v.begin(),v.end());
  6. 将n个elem拷贝给本身:vextor(n,elem);
  7. 拷贝构造函数:vector(const vector &v) ;
  1. void printVector(vector<int>& v)
  2. { //利用迭代器打印 v
  3. for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
  4. {
  5. cout << *it << " ";
  6. }
  7. cout << endl;
  8. }
  9. void text01()
  10. {
  11. vector<int> v1;
  12. for (int i = 0; i < 5; ++i)
  13. {
  14. v1.push_back(i);//向v1末尾添加数据
  15. }
  16. vector<int> v2(v1.begin(), v1.end()); //构造2
  17. vector<int> v3(5, 5); //构造3
  18. vector<int> v4(v3); //构造4
  19. cout << "打印v2: ";
  20. printVector(v2);
  21. cout << "打印v3: ";
  22. printVector(v3);
  23. cout << "打印v4: ";
  24. printVector(v4);
  25. }

2)遍历

v.begin()返回迭代器,这个迭代器指向容器中第一个数据
v.end()返回迭代器,这个迭代器指向容器元素的最后元素的下一个位置
vector<int>::iterator 拿到这种容器的迭代器类型

第一种遍历方式

  1. vector<int>::iterator pBegin = v.begin();
  2. vector<int>::iterator pEnd = v.end();
  3. while(pBegin != pEnd){
  4. cout<<*pBegin<<endl;
  5. pBegin++;
  6. }

第二种遍历方式

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

3)赋值

vector& operator=(const vector &v); 重载赋值运算符
assign(v.begin(),v.end());将[v.begin(),v.end())区间中的元素赋值给本身
assign(n,elem);将n个elem赋值给本身
  1. void printVector(vector<int>& v)
  2. { //利用迭代器打印 v
  3. for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
  4. {
  5. cout << *it << " ";
  6. }
  7. cout << endl;
  8. }
  9. void text02()
  10. {
  11. vector<int> v1,v2;
  12. for (int i = 0; i < 5; ++i)
  13. {
  14. v1.push_back(i);
  15. }
  16. v2 = v1;
  17. vector<int> v3,v4;
  18. v3.assign(v1.begin(), v1.end());
  19. v4.assign(10100);
  20. cout << "打印v2: ";
  21. printVector(v2);
  22. cout << "打印v3: ";
  23. printVector(v3);
  24. cout << "打印v4: ";
  25. printVector(v4);
  26. }

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)互换容器

swap(vec);将vec与本身元素互换
v1.swap(v2)

8)预留空间

reserve(int len);预留len个元素长度

当数据量较大时可以一开始就利用reserve预留空间

5、String

string内部封装了许多成员方法,如find,copy,delete,insert,replace等

头文件:#include<string>

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>字符串长度,就拷贝到字符串结尾结束
  1. #include<string>
  2. void test1(){
  3. string s1; //创建空字符串,使用无参构造函数
  4. const char*str = "hello";
  5. string s2(str);
  6. string s3(s2); //调用拷贝构造函数
  7. string s4(10,'a'); //将字符a复制10次
  8. string s5(s2,1);//拷贝s2所指向的字符串序列的第1个到结尾的字符
  9. }

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位置
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. int main()
  5. {
  6. string s0("");
  7. s0.push_back('a');//s0尾插入a
  8. string s1("b");
  9. s0.insert(1, s1);//在下标为1的位置插入s1的拷贝
  10. s0.insert(4, "c");//在下标为4的位置插入字符串o
  11. s0.insert(0, "hello",2);//在下标为0的位置插入"hello"的前2个字符
  12. return 0;
  13. }

拼接:

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

  1. int main(){
  2. string s1="hello";
  3. string s2="hhllo";
  4. int ret = s1.compare(s2);
  5. ……
  6. return 0;
  7. }

6)字符串存取

char& operator[](int n);通过[]方式取字符
char& at(int n);通过at方式取字符
  1. int main(){
  2. string str = "hello world"
  3. for (int i = 0;i < str.size();i++){
  4. cout << str[i] << " ";
  5. cout << str.at(i) << " ";
  6. }
  7. cout<<endl;
  8. }
  9. //字符修改:
  10. str[0] = "x";
  11. str.at(1) = "x";
  12. return 0;
  13. }

7)子串

string substr(int pos=0,int n = npos) const;返回由pos开始的n个字符组成的字符串
  1. void teste1(){
  2. string str ="abcdefg"
  3. string substr = str.substr(1,3)
  4. cout<<"substr ="<< substr << endl;
  5. string email="hello@sina.com";
  6. int pos = email.find("@");
  7. string username =email.substr(0, pos);
  8. cout<<"username:"<<username<< endl
  9. }
  10. int main(){
  11. teste1();
  12. system("pause");
  13. return0;
  14. }

6、Set

基本概念:以有序的方式存储一组唯一的元素。具体来说,std::set使用红黑树(Red-Black Tree)实现,这使得元素在插入时就会按照特定的顺序进行排序,并且保证了查找、插入和删除操作的高效性能。

注意:set不允许容器出现重复元素,multiset允许容器出现重复元素

头文件:#include<set>

遍历:

  1. #include <set>
  2. void printSet(set<int> &s){
  3. for(set<int>::iterator it=s.begin();it!=s.end;it++){
  4. cout<<*it<<" ";
  5. }
  6. cout<<endl;
  7. }

1)构造和赋值

set<T> st;默认构造函数
set(sonst set &st);拷贝构造函数
set& operator=(const set &st);重载等号操作符
  1. set<int> s1;
  2. s1.insert(10);
  3. s1.insert(10);
  4. set<int>s2(s1); //拷贝构造
  5. set<int> s3;
  6. s3=s2; //赋值

2)大小和交换

size();

返回容器中元素数目
empty();判断容器是否为空
swap(st);交换两个集合容器
  1. set<int> s1;
  2. s1.insert(10);
  3. s1.insert(20);
  4. s1.insert(30);
  5. set<int> s2;
  6. s1.insert(40);
  7. s1.insert(50);
  8. s1.insert(60);
  9. s1.swap(s2);

3)插入和删除

insert(elem);在容器中插入元素
clear();清除所有元素
erase(pos);删除pos迭代器所指的元素,返回下一个元素的选代器
erase(beg,end);删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem);删除容器中值为elem的元素。
  1. set<int> s1;
  2. s1.insert(10);
  3. s1.insert(20);
  4. s1.insert(30);
  5. s1.erase(s1.begin()); //删除
  6. s1.erase(10);
  7. s1.clear(); //清空

4)查找和统计

find(key);查找是否存在key,若存在返回该键的元素的迭代器,若不存在,返回set.end()
count(key);统计key的元素的个数

7、Queue

先进先出的数据结果,有两个出口,只有队头和队尾能被外界访问,因此不存在遍历的行为

1)构造函数

queue<T> que;queue对象默认构造形式
queue(const queue &que);拷贝构造函数

2)赋值

queue& operator=(const queue &que);重载等号操作符

3)数据存取

push(elem);往队尾添加元素
pop();从队头移除一个元素
back();返回最后一个元素
front();返回第一个元素

4)大小

empty();判断堆栈是否为空
size();返回栈的大小

三、字符串

1、简介

C语言风格:

  1. char a[5] = {'1','2','3','4','5'}; //字符数组
  2. char b[5] = {'1','2','3','4','\0'}; //字符串
  3. char greeting['h','e','l','l','o','\0'}; //字符串
  4. char greeting[]="hello";
  5. //输出结果为 hello

C++引入的string类类型(函数及其目的)

Strcpy(s1,s2)

复制字符串s2到字符串s1

Strcat(s1,s2)

连接字符串s2到s1的末尾

Strlen(s1)返回字符串s1的长度
Strcmp(s1,s2)

若s1=s2,返回0

若s1<s2,返回值小于0

若s1>s2,返回值大于0

Strchr(s1,s2)返回一个指针,指向s1中字符ch第一次出现的位置
Strstr(s1,s2)返回一个指针,指向s1中s2第一次出现的位置

2、字符串的读入

1)对字符数组得输入方法

1.1cin使用空白字符作为一次输入的结尾,并忽略该空字
  1. char word[10];
  2. cin >> word;
  3. cout<<word;
  4. //若输入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:指定分界符,表示遇到分界符后当前字符串的输入将停止,其后的会保留在输入队列中作为下一个字符串的开始。

  1. int main(){
  2. char line1[10];
  3. char line2[10];
  4. cin.getline(line1,10,'s');
  5. cin.getline(line2,10);
  6. cout<<line1<<endl;
  7. cout<<line2<<endl;
  8. return 0;
  9. }
  10. //测试:123s456
  11. //结果:
  12. line1:123
  13. line2:456

#cin.get()

cin.get(line,nums,(optional)delim)

get会在输入队列中保留最后的换行符,若不做处理可能出现问题,以下方式可以避免:

  1. cin.get(line2,10).get();
  2. cin.get(line2,10);
  3. get();
1.3数字与字符串混合输入
  1. int a,b;
  2. char s[7];
  3. cin>>a;
  4. (cin>>b).get();
  5. cin.getline(s,7);
  6. cout<<a<<" "<<b<<" "<<s;
  7. //测试:123 456 hello
  8. 结果:
  9. 123
  10. 456
  11. hello
  12. 123 456 hello

2)对string对象的输入方法

  1. string a
  2. getline(cin,a);
  3. cout<<a<<endl;

3、常见操作

1)常用函数

2)读写string

  1. string s1,s2,s3;
  2. cin>>s1;
  3. cin>>s2>>s3;
  4. //结果:
  5. nice to meet
  6. nice
  7. to
  8. meet

若要保留输入时的空格,可以使用getline

  1. string s1;
  2. getline(cin,s1);
  3. //结果:
  4. nice to meet
  5. nice to meet

3)cctype头文件

4)用for循环完成cctype各项

  1. #include<iostream>
  2. #include<string>
  3. #include<cctype>
  4. using namespace std;
  5. int main(void){
  6. string s1 = "hello world";
  7. for(auto &c : s1)
  8. c=toupper(c);
  9. cout<<s1<<endl;
  10. return 0;
  11. }
  12. //结果
  13. HELLO WORLD

四、排序

1、冒泡排序

原理:比较前后两个数字的大小,大的放在后面,依次遍历所有数字

  1. #include <iostream>
  2. #define N 1010
  3. using namespace std;
  4. int n = 6; //待排序的元素个数为6
  5. int a[N] = {0,2,3,2,11,7,6}; //待排序元素
  6. int main(){
  7. for(int i = 1;i<n;i++){ //连续交换过程
  8. //一共n-1个阶段,在第i个阶段,未排序序列长度从n-i+1到n-i
  9. for (int j = 1;j<=n-i;++j) //将序列从1到n-i+1的最大值移到n-i+1的位置
  10. if (a[j] > a[j+1]) // 将序列从1到n-i+1的最大值,移到n-i+1的位置
  11. swap(a[j],a[j+1]); // 其中j枚举的是前后交换元素的前一个元素序号
  12. }
  13. //输出
  14. for (int i=1;i<=n;++i)
  15. cout<<a[i]<<' ';
  16. cout<<endl;
  17. return 0;
  18. }

2、选择排序

原理:

  1. 遍历数组,找到最小(或最大)的元素。
  2. 将找到的最小(或最大)元素与数组的第一个元素交换位置。
  3. 排除第一个元素,对剩余的元素进行相同的操作,即在剩余的未排序部分中找到最小(或最大)的元素,并与该部分的第一个元素交换位置。
  4. 重复以上步骤,直到整个数组排序完成。

缺点:平均时间复杂度为O(n^2),空间复杂度为O(1),性能通常比较差。

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. // 选择排序函数
  5. void selectionSort(vector<int>& arr) {
  6. int n = arr.size();
  7. for (int i = 0; i < n - 1; ++i) { // 外层循环遍历数组
  8. int minIndex = i; // 假设当前元素为最小值的索引
  9. // 内层循环寻找最小值的索引
  10. for (int j = i + 1; j < n; ++j) {
  11. if (arr[j] < arr[minIndex]) { // 如果找到更小的元素,则更新最小值的索引
  12. minIndex = j;
  13. }
  14. }
  15. swap(arr[i], arr[minIndex]); // 将最小值与当前位置的元素交换位置
  16. }
  17. }
  18. int main() {
  19. // 测试选择排序函数
  20. vector<int> arr = {64, 25, 12, 22, 11};
  21. cout << "Original array: ";
  22. for (int num : arr) {
  23. cout << num << " ";
  24. }
  25. cout << endl;
  26. selectionSort(arr); // 调用选择排序函数
  27. cout << "Sorted array: ";
  28. for (int num : arr) {
  29. cout << num << " ";
  30. }
  31. cout << endl;
  32. return 0;
  33. }

3、插入排序

原理:

  1. 将数组视为两部分,一部分是已排序的部分,一部分是未排序的部分。
  2. 从未排序部分取出第一个元素,在已排序部分中从后往前逐个比较,找到合适的位置插入该元素,使得插入后的部分仍然保持有序。
  3. 重复上述过程,直到未排序部分为空,整个数组就排好序了。

优点:适合小型数据集或部分有序的数据。

  1. #include<iostream>
  2. using namespace std;
  3. int main() {
  4. int a[6] = { 2, 6, 5, 3, 4, 1}; // 待排序序列
  5. int temp, i, j;
  6. int n = 6; // 待排序元素个数
  7. // 开始插入排序
  8. for (i = 1; i < 6; i++) {
  9. // 假定第一个数是有序的,从第二个数开始枚举
  10. temp = a[i]; // 临时储存每一次需要排序的数
  11. j = i; // j用于记录当前待排序元素的位置
  12. // 在有序部分从后往前比较,将比当前元素大的元素往后移动
  13. while (j >= 1 && temp < a[j - 1]) {
  14. a[j] = a[j - 1]; // 元素往后移动
  15. j--; // 继续向前搜索
  16. }
  17. a[j] = temp; // 将待排序元素插入到合适的位置
  18. }
  19. // 输出排序后的结果
  20. for (i = 0; i < 6; i++) {
  21. cout << a[i] << " ";
  22. }
  23. cout << endl;
  24. return 0;
  25. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号