• 个人简介

    image ![] 玩崩坏:星穹铁道原神绝区零

    image 游戏学习:https://ys.mihoyo.com/cloud/#/

    https://sr.mihoyo.com/cloud/?utm_source=official#/(https://jpg.mac89.com/pic/202203/28174504_b3a04664da.jpeg) https://www.doubao.com/chat/98487760627970 ![]![image] 字符: getchar() 获取单个字符 putchar() 输出单个字符 isdigit() 判断是否为数字 isupper() 判断是否为大写 islower() 判断是否为小写 isalpha() 判断是否为字母

    字符数组(最后一个预留给'\0'): char str[100] puts(str) 输出字符串 gets(str) 输入一个字符串(包括空格,已经弃用) fgets(str,100,stdin) 获取长度为100的字符串,并且是标准输入方式,存到str中 strcat(str,str1) 在str后面连接str1 strcmp(str1,str2) 比较两个字符串返回的是正数:1大 0:一样大 负数:2大 strlen(str1) 获取字符数组的长度(不包括\0)

    字符串: getline(cin,str) 获取一整行字符串 str.substr(i,l) 从i的位置开始获取长度为l的子串 str.find(str1) 查找str1子串在str中的位置,如果没有npos(-1) str.rfind(str1) 从右边查找 str1子串在str中的位置 str.erase(i,l) 从i的位置开始删除l的长度 str.insert(i, str2); 在i的位置前,插入str2 str.size(); 获取str的长度 str.c_str(); 获取str对应的char[] str.begin(); 获取str的首地址 str.end(); 获取str的尾地址(最后一个元素后面) stoi(str) 把字符串变成数字 stol(str) 把字符串变成long long stof(str) 把字符串变成 float 将字符串转成数字:

    1.借用bitset将01字符串变成无符号整数

    string a = "1001";

    bitset<64> b(string("1001"))

    bitset<64> b(a)

    cout<<b.to_ulong()

    2.用sscanf() 函数把字符数组里面的字符串打印到数值变量里面

    int buf;

    sscanf("123456","%d",&buf)

    printf("%d\n",buf)

    3.用sprintf()把数据打印到字符数组里面

    char s[100]

    sprintf(s,"%d",123)

    4.用直接的方式

    string s = "1234";

    int n = 0;

    for(int i = 0;i<4;i++){

    n = n*10+s[i]-'0';

    }

    5.一般用法

    char buf[512] = ;

    sscanf("123456 ", "%s", buf);

    printf("%s\n", buf);

    结果为:123456

    1. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。

    sscanf("123456 ", "%4s", buf);

    printf("%s\n", buf);

    结果为:12342. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。

    sscanf("123456 abcdedf", "%[^ ]", buf);

    printf("%s\n", buf);

    结果为:123456

    1. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。

    sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);

    printf("%s\n", buf);

    结果为:123456abcdedf

    1. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。

    sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);

    printf("%s\n", buf);

    结果为:123456abcdedf

    5、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将

    非'@'的一串内容送到buf中

    sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);

    printf("%s\n", buf);

    结果为:12DDWDFF

    6、给定一个字符串"hello, world",仅保留"world"。(注意:“,”之后有一空格)

    sscanf("hello, world", "%*s%s", buf);

    printf("%s\n", buf);

    结果为:world  P.S. %*s表示第一个匹配到的%s被过滤掉,即hello,被过滤了,如果没有空格则结果为

    快读快写: #include<bits/stdc++.h> #define f_Getchar() getchar() #define f_Putchar(ch) putchar(ch) using namespace std;

    inline int read(){ // 单个字符读入 register int x = 0,t=1; register char cj =getchar(); while(cj<'0'||cj>'9'){ if(cj == '-')t--; cj = getchar(); } while(cj>='0'&&cj<='9'){ //x =(x<<1)+(x<<3)+(cj^48); x = x10+cj-'0'; cj = getchar(); } return xt; } inline void write(int x){ if(x<0){// 写入 putchar('-'); x=-x; } if(x>9){ write(x/10); } putchar(x%10+'0'); putchar('\n'); return; } //string 整行快读读入 inline void inputL(char* s){ char ch = f_Getchar() ; while(ch == '\n')ch = f_Getchar() ; while(ch != '\n')*s = ch,++ s,ch = f_Getchar() ; s = '\0' ; return ; } // 确定字符串长度情况下 inline void inputSs(char s,unsigned long long len){ char ch = f_Getchar() ; while(ch == ' ' || ch == '\n')ch = f_Getchar() ; while((len --) && (ch != ' ' && ch != '\n')){ *s = ch,++ s,ch = f_Getchar() ; s = '\0' ; } return ; } // 正常字符串快写 inline void outputS(const char s){ while(*s)f_Putchar(s ++) ; return ; } //输出一行字符串 inline void outputSL(const char s){ while(*s && *s != '\n')f_Putchar(*s ++) ; return ; } int main(){ // int m,n; // m = read(); // n = read(); // write(m); // write(n); char s[100]; inputL(s); outputS(s); }

    通常会填充字符串某些位置的值,第一反应是遍历,时间复杂度为O(n),其实也不算久,但是有更好的方 法,耗时更少,下面介绍两种方法 方法1 memset 头文件 C:#include<string.h> C++:#include<cstring> or #include<string.h> 函数原型 void *memset(void *_Dst, int _Val, size_t _Size) _Dst:填充内容起始地址 _Val:要被设置的值。该值以int形式传递,但是函数在填充内存块时是使用该值的无符号字符形式 _Size:填充字节数 PS:函数只能用来填充char型数组,如果填充int型数组,除了0和-1,其他数值不能(否则最后的赋值非 你想象) 原因:memset中的val是采用无符号形式字符形式表示,即val为多少,只取一个低位字节 example:val = 124 = 0111 1100 memset(a, 124, sizeof(a)); a = {2088533116, 2088533116, …} = { 0111 1100 | 0111 1100 | 0111 1100 | 0111 1100, … } 至于为什么0和-1就可以了,建议看下内存中数据存储方式(补码) 0 -> 补码: 0000 0000 0000 0000 0000 0000 0000 0000 -1-> 补码: 1111 1111 1111 1111 1111 1111 1111 1111 int a[5]; memset(a, 0, sizeof(a)); memset(&a[0], 0, sizeof(a)); memset(a, 0, 5 * sizeof(int)); int a[5][5]; memset(a, 0, sizeof(a)); memset(a[0], 0, sizeof(a)); memset(&a[0][0], 0, sizeof(a)); memset(a, 0, 25 * sizeof(int)); 方法2 fill 头文件 #include <iostream> 函数原型 template <class ForwardIterator, class T> void fill (ForwardIterator first, ForwardIterator last, const T& val) { while (first != last) { *first = val; ++first; } } first:起始迭代器 last:结束迭代器,注意不包含最后一个元素 val:填充的值 PS:fill不仅可以对数组赋值,也可以对vector赋值 example: int a[5]; fill(a, a + 5, 0); fill(&a[0], a + 5, 0); fill(&a[0], &a[5], 1); // 因为是"不到last" fill(&a[0], a + sizeof(a) / sizeof(int), 1); fill(&a[0], a + sizeof(a) / sizeof(a[0]), 1); int a[5][5]; // fill(a, a + 5 * 5, 0); // 报错,'const int' to 'int [5]' // fill(&a, &a + 5 * 5, 0); // 报错,'const int' to 'int [5][5]' // fill(&a[0], &a[0] + 5 * 5, 0); // 报错,'const int' to 'int [5]' fill(a[0], a[0] + 5 * 5, 0); fill(&a[0][0], &a[5][5], 0); fill(&a[0][0], &a[0][0] + 5 * 5, 0); fill(&a[0][0], &a[0][0] + sizeof(a) / sizeof(int), 0);

    image image image vector是 C++ 标准模板库(STL)里极为实用的容器,它能当作动态数组使用,可依据运行时的需求灵活调整大小 1.一维vector

    1. 头文件包含 使用vector前,要包含<vector>头文件: #include <vector>
    2. 一维vector的创建与初始化 默认初始化:创建一个空的vector,之后可动态添加元素。
    #include <iostream>
    #include <vector>
    
    int main() {
        vector<int> v1;  // 创建一个空的存储int类型元素的vector
        return 0;
    }
    

    指定大小初始化:创建时指定元素数量,元素默认初始化为对应类型的默认值(数值类型通常为 0)。

    #include <iostream>
    #include <vector>
    int main() {
        vector<int> v2(5);  // 创建包含5个元素的vector,元素初始值为0
        for (int i = 0; i < v2.size(); ++i) {
            cout << v2[i] << " ";
        }
       cout << endl;
        return 0;
    }
    

    指定大小和初始值初始化:创建时指定元素数量和初始值。

    #include <iostream>
    #include <vector>
    
    int main() {
        vector<int> v3(5, 10);  // 创建包含5个元素的vector,每个元素初始值为10
        for (int i = 0; i < v3.size(); ++i) {
           cout << v3[i] << " ";
        }
       cout << endl;
        return 0;
    }
    

    列表初始化:使用花括号{}直接给出初始元素。

    #include <iostream>
    #include <vector>
    
    int main() {
        vector<int> v4 = {1, 2, 3, 4, 5};  // 使用列表初始化vector
        for (int i = 0; i < v4.size(); ++i) {
            cout << v4[i] << " ";
        }
       cout << endl;
        return 0;
    }
    
    1. 一维vector的常用操作 添加元素:用push_back()在vector末尾添加元素。
    #include <iostream>
    #include <vector>
    
    int main() {
        vector<int> v;
        v.push_back(1);
        v.push_back(2);
        for (int i = 0; i < v.size(); ++i) {
            cout << v[i] << " ";
        }
        cout << endl;
        return 0;
    }
    

    访问元素:可通过下标[]或迭代器访问元素。

    #include <iostream>
    #include <vector>
    
    int main() {
        vector<int> v = {1, 2, 3};
        // 使用下标访问
        cout << v[1] << endl;
        // 使用迭代器访问
        for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
            cout << *it << " ";
        }
        cout << endl;
        return 0;
    }
    

    删除元素:用pop_back()删除末尾元素,erase()删除指定位置元素。

    #include <iostream>
    #include <vector>
    int main() {
        vector<int> v = {1, 2, 3, 4, 5};
        v.pop_back();  // 删除末尾元素
        v.erase(v.begin() + 1);  // 删除索引为1的元素
        for (int i = 0; i < v.size(); ++i) {
            cout << v[i] << " ";
        }
        cout << endl;
        return 0;
    }
    

    二维vector

    1. 二维vector的创建与初始化 默认初始化:先创建外层vector,之后再逐个添加内层vector。
    #include <iostream>
    #include <vector>
    
    int main() {
        vector<vector<int>> v1;  // 创建一个空的二维vector
       vector<int> row1 = {1, 2, 3};
        vector<int> row2 = {4, 5, 6};
        v1.push_back(row1);
        v1.push_back(row2);
        return 0;
    }
    

    指定大小初始化:创建时指定外层和内层vector的大小,元素默认初始化为对应类型的默认值。

    #include <iostream>
    #include <vector>
    
    int main() {
        int rows = 3;
        int cols = 4;
       vector<vector<int>> v2(rows, vector<int>(cols));  // 创建3行4列的二维vector,元素初始值为0
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                cout << v2[i][j] << " ";
            }
            cout << endl;
        }
        return 0;
    }
    

    指定大小和初始值初始化:创建时指定外层和内层vector的大小,并为元素设置初始值。

    #include <iostream>
    #include <vector>
    
    int main() {
        int rows = 3;
        int cols = 4;
        int initValue = 1;
        vector<vector<int>> v3(rows, vector<int>(cols, initValue));  // 创建3行4列的二维vector,元素初始值为1
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                cout << v3[i][j] << " ";
            }
            cout << endl;
        }
        return 0;
    }
    
    1. 二维vector的常用操作 访问元素:使用双重下标[][]访问元素。
    #include <iostream>
    #include <vector>
    int main() {
        vector<vector<int>> v = {{1, 2}, {3, 4}};
        cout << v[1][0] << endl;  // 输出3
        return 0;
    }
    

    修改元素:直接通过双重下标赋值来修改元素值。

    #include <iostream>
    #include <vector>
    
    int main() {
        vector<vector<int>> v = {{1, 2}, {3, 4}};
        v[1][0] = 10;
       cout << v[1][0] << endl;  // 输出10
        return 0;
    }
    

    添加行:使用push_back()添加新的一行。

    #include <iostream>
    #include <vector>
    
    int main() {
        vector<vector<int>> v = {{1, 2}, {3, 4}};
        vector<int> newRow = {5, 6};
        v.push_back(newRow);
        for (int i = 0; i < v.size(); ++i) {
            for (int j = 0; j < v[i].size(); ++j) {
                cout << v[i][j] << " ";
            }
            cout << endl;
        }
        return 0;
    }
    

    **一、目标** 理解 set 和 unordered_set 的基本概念和用途。 掌握 set 和 unordered_set 的常见操作,如插入、查找、删除等。 了解 set 和 unordered_set 的性能差异,能够根据实际需求选择合适的容器。 **二、集合容器概述** (一)集合的定义 集合是一种存储唯一元素的数据结构,每个元素在集合中只能出现一次。 (二)C++ 中的集合容器 C++ 标准库提供了两种集合容器:set 和 unordered_set。 (三)用途 常用于去重、查找特定元素等场景。 **三、set 容器介绍** (一)基本概念 set 是一个有序的集合容器,它基于红黑树(一种自平衡的二叉搜索树)实现。元素在 set 中会按照一定的顺序自动排序,默认是升序。 (二)头文件包含 要使用 set,需要包含 <set> 头文件,示例代码如下: `#include <set>` (三)声明和初始化 以下是一个声明并初始化 set 容器,然后插入元素并遍历的示例: ``` #include <iostream> #include <set> using namespace std; int main() { // 声明一个存储整数的 set set<int> mySet; // 插入元素 mySet.insert(3); mySet.insert(1); mySet.insert(2); // 遍历 set for (auto it = mySet.begin(); it != mySet.end(); ++it) { cout << *it << " "; } cout << endl; return 0; } ``` (四)输出结果 上述代码的输出结果为: 1 2 3 可以看到,元素会自动按照升序排列。 **四、set 的常见操作** (一)插入元素 使用 insert 方法向 set 中插入元素,示例如下: ``` set<int> mySet; mySet.insert(5); mySet.insert(10); ``` (二)查找元素 使用 find 方法查找元素,若找到则返回指向该元素的迭代器,若未找到则返回 end() 迭代器,示例如下: ``` auto it = mySet.find(5); if (it != mySet.end()) { cout << "Element found!" << endl; } else { cout << "Element not found!" << endl; } ``` (三)删除元素 使用 erase 方法删除元素,示例如下: `mySet.erase(5);` (四)获取元素数量 使用 size 方法获取 set 中元素的数量,示例如下: `size_t size = mySet.size();` **五、unordered_set 容器介绍** (一)基本概念 unordered_set 是一个无序的集合容器,它基于哈希表实现。元素在 unordered_set 中没有特定的顺序,插入和查找操作的平均时间复杂度为 。 (二)头文件包含 要使用 unordered_set,需要包含 <unordered_set> 头文件,示例代码如下: ``` #include <unordered_set> ``` (三)声明和初始化 以下是一个声明并初始化 unordered_set 容器,然后插入元素并遍历的示例: ``` #include <iostream> #include <unordered_set> int main() { // 声明一个存储整数的 unordered_set unordered_set<int> myUnorderedSet; // 插入元素 myUnorderedSet.insert(3); myUnorderedSet.insert(1); myUnorderedSet.insert(2); // 遍历 unordered_set for (auto it = myUnorderedSet.begin(); it != myUnorderedSet.end(); ++it) { cout << *it << " "; } cout << endl; return 0; } ``` (四)输出结果 元素输出顺序不确定,例如可能是: 3 1 2 **六、unordered_set 的常见操作** (一)插入元素 使用 insert 方法向 unordered_set 中插入元素,示例如下: ``` unordered_set<int> myUnorderedSet; myUnorderedSet.insert(5); myUnorderedSet.insert(10); ``` (二)查找元素 使用 find 方法查找元素,若找到则返回指向该元素的迭代器,若未找到则返回 end() 迭代器,示例如下: ``` auto it = myUnorderedSet.find(5); if (it != myUnorderedSet.end()) { cout << "Element found!" << endl; } else { cout << "Element not found!" << endl; } ``` (三)删除元素 使用 erase 方法删除元素,示例如下: ``` myUnorderedSet.erase(5); ``` (四)获取元素数量 使用 size 方法获取 unordered_set 中元素的数量,示例如下: `size_t size = myUnorderedSet.size();` **七、set 和 unordered_set 的性能比较** 205f200699571ff292bff0be89f81adf.png 性能分析 set 基于红黑树,插入、查找和删除操作的时间复杂度为$O(logn)$ ,但元素是有序的。 unordered_set 基于哈希表,插入、查找和删除操作的平均时间复杂度为$O(1)$ ,但元素是无序的,且在最坏情况下(哈希冲突严重)时间复杂度会退化为 $O(n)$。 **八、选择合适的容器** (一)需要有序元素 如果需要元素按照一定的顺序存储,例如升序或降序,应该选择 set。 ``` set<int> sortedSet; sortedSet.insert(3); sortedSet.insert(1); sortedSet.insert(2); ``` // 元素会自动按升序排列 (二)对性能要求高 如果对插入、查找和删除操作的性能要求较高,且不关心元素的顺序,应该选择 unordered_set。 ``` unordered_set<int> fastSet; fastSet.insert(3); fastSet.insert(1); ``` fastSet.insert(2); // 插入和查找操作平均时间复杂度为 O(1) **九、实际案例:去重** (一)使用 set 去重 ``` #include <iostream> #include <set> #include <vector> int main() { vector<int> numbers = {1, 2, 2, 3, 3, 3}; set<int> uniqueNumbers(numbers.begin(), numbers.end()); for (auto num : uniqueNumbers) { cout << num << " "; } cout << endl; return 0; } ``` (二)使用 unordered_set 去重 ``` #include <iostream> #include <unordered_set> #include <vector> int main() { vector<int> numbers = {1, 2, 2, 3, 3, 3}; unordered_set<int> uniqueNumbers(numbers.begin(), numbers.end()); for (auto num : uniqueNumbers) { cout << num << " "; } cout << endl; return 0; }

  • 通过的题目

  • 最近活动

题目标签

一本通编程启蒙
307
小学生C++趣味编程
155
来源
146
循环结构
133
基础语法
114
分支结构
92
顺序结构
90
函数
62
数组
47
力扣
33
字符串
29
搜索
24
难度
24
洛谷
22
入门
21
DFS
16
多重循环
16
结构体
12
排序
9
BFS
8