机试指南:3-4章

文章目录

  • 第3章 排序与查找
    • (一) 排序
      • 1.sort函数:sort(first,last,comp)
      • 2.自定义比较规则
      • 3.C++函数重载:同一个函数名,有不同的参数列表
      • 4.机试考试最重要的事情:能把你曾经做过的题目,满分地做出来
      • 5.例题
        • 例题1:对n个数进行排序
        • 例题2:整数奇偶排序 (北京大学机试上机)
        • 例题3:成绩排序1(清华大学复试上机题)
          • 结构体 + . 运算符
        • 例题4:成绩排序2
        • 例题5:成绩排序3
      • 6.习题
        • 习题1:特殊排序
        • 习题2:小白鼠排队
        • 习题3:奥运排序问题 (难度:困难)
    • (二) 查找
      • 1.顺序查找(Liner Search)
        • (1)泛型函数 find()
        • (2)顺序查找存在的问题
        • (3)时间复杂度、空间复杂度
      • 2.二分查找(Binary Search)
      • 3.使用map替代二分查找
        • (1)指针迭代器 iterator
      • 4.例题
        • 例题1:找x
        • 例题2:查找
          • 解法1:顺序查找
          • 解法2:二分查找 (代码繁琐)
          • 解法3:map
          • 解法4:set
        • 例题3:找位置 (Mid-Hard)
      • 5.习题
        • 习题1:找最小数
        • 习题2:打印极值点下标 (难度:入门)
        • 习题3:差分计数 (难度:简单)
          • TLE问题:处理大数据集的策略,降低算法的时间复杂度
  • 第4章 字符串
    • 1.C字符数组 char str[1000] :处理输入、输出
      • (1)原理
      • (2)基本操作
      • (2)优势与劣势
        • ①C风格字符数组:char str[100]
        • ②C++字符串:string
    • 2.C++ 字符串string :处理更复杂问题
      • (1)基本操作
      • (2)增删改查遍历
      • (3)子串操作
      • (4)其他操作
        • 1.string和数值相互转换
        • 2.string的输入输出
        • 3.一次读入一行
          • (1)C语言:fgets()
          • (2)C++:cin.getline()
    • 3.例题
      • 例题1:单词个数统计 (难度:中等)
      • 例题2:浮点数加法 【高精度运算】(难度:Mid-Hard)
      • 例题3:W的密码 (难度:困难)
    • 4.习题
      • 习题1:统计字符串中各类型字符的个数 (难度:入门)
      • 习题2:大写字母个数统计 (难度:入门)
      • 习题3:首字母大写 (难度:简单)
      • 习题4:寻找变化前的01序列 【字符串替换】 (难度:简单)
      • 习题5:大整数排序 (难度:简单)
      • 习题6:单词替换 【字符串替换】(难度:中等)
      • 习题7:skew数 【进制转换】(难度:)
      • 习题8:复制、剪切、粘贴 (难度:)

第3章 排序与查找

(一) 排序

1.sort函数:sort(first,last,comp)

C++引入了基于快速排序的排序函数:sort()

1.sort(first,last,comp)函数的三个参数:
①first为待排序序列起始地址
②last为最后一个元素的后一个位置的地址 (尾后指针)
③comp为排序方式的函数名(任意起),不填写默认升序排序。

sort(arr,arr+6);
sort(arr,arr+6,comp);

sort(vec.beign(),vec.end());
sort(vec.beign(),vec.end(),comp);

2.C语法:数组名作为函数参数,会退化为指针。 a r r → & a r r [ 0 ] \rm arr→\&arr[0] arr&arr[0]
arr[i]是元素
arr是0号元素的地址。arr+i是i号元素的地址。
③C语言数组的数组名,可以当地址/指针来使用。&arr[i] 和 arr+i 等价


头文件:

#include <algorithm>
using namespace std;

排序静态数组、动态数组:

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

bool compare(int lhs,int rhs){
    return lhs >= rhs;  //降序排序
}

int main() {
    int arr[6] = {2,4,6,1,3,5};
    sort(arr,arr+6); //数组名作为函数参数,退化为指针 : arr -> &arr[0]
    vector<int> vec = {2,4,6,1,3,5};
    sort(vec.begin(),vec.end());
    sort(vec.begin(),vec.end(),compare);
    return 0;
}

左闭右开 [arr,arr+n),尾后
在这里插入图片描述


2.自定义比较规则

①compare函数的返回类型是bool
②默认比较方式是 <
不发生交换,返回真


在这里插入图片描述


在这里插入图片描述


3.C++函数重载:同一个函数名,有不同的参数列表

比较的题目,重点就是设计bool comp(int lhs,int rhs)函数。//不发生交换时为真

在这里插入图片描述


4.机试考试最重要的事情:能把你曾经做过的题目,满分地做出来

最重要的不是把所有题目都写了个差不多,没用,差一点就是零分。要么满分要么零分。
最重要的是,把你曾经做过的题目,满分地做出来。
泥鳅老师:你就算是天纵奇才,也不可能在机试的时候把你从来没做过的题目做出来。就是一个熟练度的问题。


5.例题

例题1:对n个数进行排序

样例输入:
4
1 4 3 2

样例输出:
1 2 3 4

#include <cstdio>
#include <algorithm>
using namespace std;

int main(){
    int n;
    int arr[101];
    scanf("%d",&n);
    for(int i=0;i<n;++i){
        scanf("%d",&arr[i]);//&arr[i] 和 arr+i 等价
    }
    sort(arr,arr+n);//排序
    for(int i=0;i<n;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
}

例题2:整数奇偶排序 (北京大学机试上机)

提交网址:https://www.acwing.com/problem/content/3449/

在这里插入图片描述

解法1:奇偶分别排序

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

bool compare(int lhs,int rhs){
    return lhs >= rhs;
}

int main() {
    int arr[10];
    vector<int> vec1;	//存奇数
    vector<int> vec2;	//存偶数
    for(int i = 0 ; i < 10; ++i){
        scanf("%d",&arr[i]);  //arr+i
        if(arr[i]%2 == 0){
            vec2.push_back(arr[i]);
        }else{
            vec1.push_back(arr[i]);
        }
    }
    sort(vec1.begin(),vec1.end(),compare); //奇数降序
    sort(vec2.begin(),vec2.end());
    vector<int>::iterator it;
    for(it = vec1.begin(); it != vec1.end(); ++it)  printf("%d ",*it);
    for(it = vec2.begin(); it != vec2.end(); ++it)  printf("%d ",*it);
    printf("\n");
    return 0;
}

解法2:整体排序,重点在于构建 compare函数


    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    bool compare(int lhs, int rhs) {
        if (lhs % 2 == 1 && rhs % 2 == 0) {
            return true;
        }
        else if (lhs % 2 == 1 && rhs % 2 == 1 && lhs > rhs) {
            return true;
        }
        else if (lhs % 2 == 0 && rhs % 2 == 0 && lhs < rhs) {
            return true;
        }
        else {
            return false;
        }
    }
    int main() {
    
        int arr[10];
        for (int i = 0; i < 10; ++i) {
            scanf("%d", &arr[i]); // arr + i
        }
        sort(arr, arr + 10, compare);
        for (int i = 0; i < 10; ++i) {
            printf("%d ", arr[i]);
        }
        printf("\n");
        return 0;
    }

例题3:成绩排序1(清华大学复试上机题)

提交网址:https://www.acwing.com/problem/content/3379/
https://www.nowcoder.com/share/jump/2891302591706172383452

在这里插入图片描述


结构体 + . 运算符

解法1:结构体 + vector

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

struct Student{
    int number;
    int score;
};

bool comp(Student lhs,Student rhs){
    if(lhs.score < rhs.score)  return true;
    else if(lhs.score == rhs.score && lhs.number < rhs.number)  return true;
    else    return false;
}

int main(){
    int N,p,q;
    scanf("%d",&N);
    vector<Student> stu(N);
    for(int i = 0 ; i < N; ++i){
        scanf("%d%d",&stu[i].number,&stu[i].score);
    }
    sort(stu.begin(),stu.end(),comp);
    for(int i = 0; i < N; ++i){
        printf("%d %d\n",stu[i].number,stu[i].score);
    }
    return 0;
}

解法2:结构体 + 数组

#include <cstdio>
#include <algorithm>
using namespace std;

struct Student {
    int num;
    int grade;
};//类的分号不要省略

bool comp(Student lhs, Student rhs) {
    //不发生交换为真
    if (lhs.grade < rhs.grade) {
        return true;
    } else if (lhs.grade == rhs.grade && lhs.num < rhs.num) {
        return true;
    } else {
        return false;
    }
}

int main() {
    int n;
    Student arr[100];
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d%d", &arr[i].num, &arr[i].grade);
    }
    sort(arr, arr + n, comp);
    for (int i = 0; i < n; ++i) {
        printf("%d %d\n", arr[i].num, arr[i].grade);
    }
}

例题4:成绩排序2

提交网址:https://www.acwing.com/problem/content/3378/

在这里插入图片描述
在这里插入图片描述

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct Student{
    char name[20];
    int score;
    int seq; //序号成员,实现稳定排序
};

bool compare0(Student lhs,Student rhs){  //0表示降序
    if(lhs.score > rhs.score)                          return true;
    else if(lhs.score==rhs.score && lhs.seq < rhs.seq)  return true;
    else                                                return false;
}

bool compare1(Student lhs,Student rhs){  //1表示升序
    if(lhs.score < rhs.score)                           return true;
    else if(lhs.score==rhs.score && lhs.seq < rhs.seq)  return true;
    else                                                return false;
}

int main() {
    int N;
    scanf("%d",&N);
    int method;
    scanf("%d",&method);
    vector<Student> vec(N);
    for(int i = 0; i < N; ++i){
        scanf("%s%d",&vec[i].name,&vec[i].score);
        vec[i].seq = i;
    }
    if(method == 0)     sort(vec.begin(),vec.end(),compare0);
    else                sort(vec.begin(),vec.end(),compare1);
    for(int i = 0; i < N; ++i){
        printf("%s %d\n",vec[i].name,vec[i].score);
    }
    return 0;
}

纠错

在这里插入图片描述
纠错1:
要么上边声明的时候加上长度
要么下边初始化一个Student,用Pushback
你这样声明的vec,长度为0,当然不能直接赋值

纠错2:
稳定性,等号的问题,注意

纠错3:
不要忘了对seq赋值:vec[i].seq = i;


例题5:成绩排序3

提交网址:http://t.cn/E9gyHM1
在这里插入图片描述

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct Student{
    char name[20];
    int score;
    int seq; //为了保证稳定性
};

bool comp0(Student lhs,Student rhs){  //0表示降序
    if(lhs.score > rhs.score)  return true;
    else if(lhs.score==rhs.score && lhs.seq < rhs.seq) return true;
    else  return false;
}

bool comp1(Student lhs,Student rhs){  //1表示升序
    if(lhs.score == rhs.score)  return lhs.seq < rhs.seq;
    else                        return lhs.score < rhs.score;
}

int main(){
    int n;
    while(scanf("%d",&n) != EOF){
        int order;
        scanf("%d",&order);
        vector<Student> vec;
        for(int i = 0; i < n; ++i){
            Student stu;
            scanf("%s%d",&stu.name,&stu.score);
            vec.push_back(stu);
            vec[i].seq = i;
        }
        if(order==0)    sort(vec.begin(),vec.end(),comp0);
        else            sort(vec.begin(),vec.end(),comp1);
        for(int i = 0; i < n; ++i){
            printf("%s %d\n",vec[i].name,vec[i].score);
        }
    }
    return 0;
}

6.习题

习题1:特殊排序

提交网址:http://t.cn/E9gio39

在这里插入图片描述

#include <cstdio>
#include <algorithm>
using namespace std;

int main() {
    int n;
    scanf("%d",&n);
    int arr[1010];
    int max = 0;
    for(int i = 0; i < n; ++i){
        scanf("%d",&arr[i]);
        if(arr[i] > max)    max = arr[i];
    }
    printf("%d\n",max);
    sort(arr,arr+n);
    for(int i = 0; i < n-1; ++i){ //少输出一个最大值,只到n-1
        printf("%d ",arr[i]);
    }
    if(n==1) printf("-1\n");
    return 0;
}

习题2:小白鼠排队

提交网址:http://t.cn/E9gXh9Z

在这里插入图片描述


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct Mouse{
    int weight;
    char color[20];
};

bool comp(Mouse lhs,Mouse rhs){
    return lhs.weight >= rhs.weight;
}

int main() {
    int n;
    scanf("%d",&n);
    vector<Mouse> vec(n);
    for(int i = 0; i < n; ++i){
        Mouse mouse;
        scanf("%d%s",&vec[i].weight,&vec[i].color);
    }
    sort(vec.begin(),vec.end(),comp);
    for(int i = 0; i < n; ++i){
        printf("%s\n",vec[i].color);
    }
    return 0;
}

习题3:奥运排序问题 (难度:困难)

提交网址:http://t.cn/E9gYpyl

在这里插入图片描述
在这里插入图片描述


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

struct country{
    int gold; //金牌
    int medal; //奖牌
    int people; //人口(百万)
    double gold_people = gold/people;   //金牌人口比例
    double medal_people = medal/people;  //奖牌人口比例
};

bool compare1(country lhs,country rhs){ //按金牌总数 降序排名
    return lhs.gold > rhs.gold;
}
bool compare2(country lhs,country rhs){ //按奖牌总数 降序排名
    return lhs.medal > rhs.medal;
}
bool compare3(country lhs,country rhs){ //按金牌人口比例 降序排名
    return lhs.gold_people > rhs.gold_people;
}
bool compare4(country lhs,country rhs){ //按奖牌人口比例 降序排名
    return lhs.medal_people > rhs.medal_people;
}

int main() {
    int N,M;  //N为总国家数,M为需要给出排名的国家数
//    while(scanf("%d",&N) != EOF){
        scanf("%d",&N);
        scanf("%d",&M);
        vector<country> vec;
        for(int i=0; i<N; ++i){
            country cty;
            scanf("%d %d %d",&cty.gold,&cty.medal,&cty.people);
            vec.push_back(cty);
        }
        //统计需要排名的国家序号
        vector<int> need_sort;
        int x;
        for(int i = 0; i < M; ++i){
            scanf("%d",&x);
            need_sort.push_back(x);
        }
        //对M个国家进行排名



//    }
    return 0;
}



(二) 查找

1.顺序查找(Liner Search)

顺序查找的问题:效率不够高。
n个元素,顺序查找,时间复杂度为O(n²)。若数据量规模n在105,则会OJ超时。需要采取一些策略降低时间复杂度。


(1)泛型函数 find()

find(begIt,endIt,x)

#include <algorithm> //头文件

vector<int>::iterator it;
it = find(vec.vegin(),vec.end(),x);
if(it == vec.end()){
	printf("-1\n");
}else{
	pirntf("%d\n",it - vec.begin());  //偏移量,即数组下标
}

在这里插入图片描述


(2)顺序查找存在的问题

①顺序查找:O(N)
②二分查找:O(logN),但需要 排序
③哈希查找:O(1),但需要 额外空间

在这里插入图片描述

(3)时间复杂度、空间复杂度

0.O()计数法:忽略常系数、忽略低阶项
1.时间复杂度:指令执行次数
2.空间复杂度:额外内存空间



2.二分查找(Binary Search)

1.二分查找(折半查找),只能在有序的数据结构中使用,需要先排序。

2.基于比较的排序,时间复杂度最好为O(nlogn)

3.N的元素,查找M次的时间复杂度:O(NlogN + M×logN)

在这里插入图片描述

在这里插入图片描述
二分查找(需要排序)适用于:给定一份数据,要查很多次。
若每查一次,数据都改,那就用顺序查找,不需要排序。

mid = (left + right)/2;
left = mid + 1;    /收缩区间,注意 +1 -1,避免二分查找死循环。
right = mid - 1;



3.使用map替代二分查找

map:空间换时间。如果程序对空间要求不高,可以用map代替二分查找。若空间卡的比较死,则还是得用二分查找。(二分查找的代码比较容易写错)

①二分查找:查找的时间复杂度O(logN),不需要空间。代码较长,繁琐,易出错。
②map:查找的时间复杂度O(logN),需要一定的空间。底层是红黑树。
③unordered_map:查找的时间复杂度O(1),需要更多的空间。底层是哈希表。

map的底层:二叉搜索树(BST)。
①在Windows下,会进一步优化为:平衡二叉树(AVL树)
②在Linux下,会进一步优化为:红黑树

在这里插入图片描述


(1)指针迭代器 iterator

findIndex.begin():第一个元素的指针
findIndex.end():最后一个元素的后面一个位置的指针,尾后指针
findIndex.find():查找某个元素的指针

if(findIndex.find(findNum) == findIndex.end()) //说明没有找到

4.例题

例题1:找x

提交网址:http://t.cn/E9gHFnS

在这里插入图片描述


#include <cstdio>

int main() {
    int n;
    scanf("%d",&n);
    int arr[210];
    for(int i = 0; i < n; ++i){
        scanf("%d",&arr[i]);
    }
    int x;
    bool flag = false;
    scanf("%d",&x);
    for(int i = 0; i < n; ++i){
        if(arr[i] == x){
            printf("%d\n",i);
            flag = true;
            break;
        }
    }
    if(flag == false)  printf("-1\n");
    return 0;
}

例题2:查找

提交网址:https://www.acwing.com/problem/content/3545/

在这里插入图片描述


解法1:顺序查找
#include <cstdio>

int main() {
    int n,m,a[110],b[110];
    scanf("%d",&n);
    for(int i = 0; i < n; ++i){
        scanf("%d",&a[i]);
    }
    scanf("%d",&m);
    for(int i = 0; i < m; ++i){
        scanf("%d",&b[i]);
    }
    for(int j = 0; j < m; ++j){
        bool flag = false;
        for(int i = 0; i < n; ++i){
            if(a[i] == b[j]){
                printf("YES\n");
                flag = true;
                break;	//两层for循环时,break只能跳出一层循环
            }
        }
        if(flag == false) printf("NO\n");
    }
    return 0;
}

解法2:二分查找 (代码繁琐)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int n;
    scanf("%d",&n);
    vector<int> a(n);
    for(int i = 0; i < n; ++i){
        scanf("%d",&a[i]);
    }
    sort(a.begin(),a.end());
    int m,b;
    scanf("%d",&m);
    for(int i = 0; i < m; ++i){
        scanf("%d",&b);
        //二分查找
        int left = 0, right = n-1;
        while(left <= right){
            int mid = (left+right)/2;
            if(b == a[mid]){
                printf("YES\n");
                break;
            }else if(b < a[mid]){
                right = mid-1;
            }else{
                left  = mid+1;
            }
        }
        if(left > right)  printf("NO\n");
    }
    return 0;
}

解法3:map

对map使用find()函数,查找的是

#include <cstdio>
#include <map>
using namespace std;

int main(){
    int n,a;
    map<int,int> mymap;
    scanf("%d",&n);
    for(int i = 0; i < n; ++i){
        scanf("%d",&a);
        mymap.insert({a,i}); //key:元素的值,value:元素的位置
    }
    int m,b;
    scanf("%d",&m);
    for(int i = 0; i < m; ++i){
        scanf("%d",&b);     对map使用find(),查找的是键
        if(mymap.find(b) != mymap.end())    printf("YES\n");
        else                                printf("NO\n");
    }
    return 0;
}

解法4:set
#include <cstdio>
#include <vector>
#include <set>
using namespace std;

int main() {
    int n,x;
    scanf("%d",&n);
    set<int> a;
    for(int i = 0; i < n; ++i){
        scanf("%d",&x);
        a.insert(x);
    }
    int m,b;
    scanf("%d",&m);
    for(int i = 0; i < m; ++i){
        scanf("%d",&b);
        if(a.find(b) != a.end())      printf("YES\n");
        else                          printf("NO\n");
    }
    return 0;
}

例题3:找位置 (Mid-Hard)

提交网址:https://www.acwing.com/problem/content/3613/

在这里插入图片描述

#include <cstdio>
#include <vector>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;

int main() {
    char str[110] = {0};
    scanf("%s",str);
    multimap<char,int> mymap;
    vector<char> seq;  //记录每个字符出现的先顺序
    for(int i = 0; i < strlen(str); ++i){  //str[i] != '\0'
        if(find(seq.begin(),seq.end(),str[i]) == seq.end()){ //说明字符str[i]是第一次出现
            seq.push_back(str[i]);                           //则加入seq中,即记录字符出现的顺序
        }
        mymap.insert({str[i],i});
    }
    vector<char>::iterator it; //it是字符出现顺序seq的迭代器
    multimap<char,int>::iterator it1;
    for(it = seq.begin(); it != seq.end(); ++it){
        if(mymap.count(*it) > 1){  //该字符在mymap中重复出现
            bool isFirst = true;    //引入isFirst,为了去掉每行结尾的逗号
            for(it1 = mymap.begin(); it1 != mymap.end(); ++it1){
                if(it1->first == *it){  //seq中的字符和mymap中的键 相匹配时
                    if(isFirst == false){
                        printf(",");
                    }
                    printf("%c:%d",it1->first,it1->second);
                    isFirst = false;
                }
            }
            printf("\n");
        }
    }
    return 0;
}



5.习题

习题1:找最小数

提交网址:http://t.cn/E9gekWa

在这里插入图片描述


结构体数组:

#include <cstdio>
#include <algorithm>
using namespace std;

struct NUM{
    int x;
    int y;
};

bool comp(NUM lhs,NUM rhs){
    if(lhs.x == rhs.x){
        return lhs.y < rhs.y;
    }else{
        return lhs.x < rhs.x;
    }
}

int main(){
    int n;
    scanf("%d",&n);
    NUM num[1010]; //结构体数组
    int x,y;
    for(int i = 0; i < n; ++i){
        scanf("%d%d",&num[i].x,&num[i].y);
    }
    sort(num,num+n,comp);
    printf("%d %d\n",num[0].x,num[0].y);
    return 0;
}

习题2:打印极值点下标 (难度:入门)

提交网址:https://www.acwing.com/problem/content/3440/

在这里插入图片描述


#include <cstdio>

int main() {
    int n;
    scanf("%d",&n);
    int arr[110];
    for(int i = 0; i < n; ++i){
        scanf("%d",&arr[i]);
    }
    //判断左端点
    if(arr[0] != arr[1])  printf("0 ");
    //判断中间
    for(int i = 1 ; i < n-1; ++i){
        if( (arr[i]>arr[i-1] && arr[i]>arr[i+1])  || (arr[i]<arr[i-1] && arr[i]<arr[i+1]) ){
            printf("%d ",i);
        }
    }
    //判断右端点
    if(arr[n-1] != arr[n-2])    printf("%d\n",n-1);
    return 0;
}

习题3:差分计数 (难度:简单)

提交网址:https://www.acwing.com/problem/content/5080/

在这里插入图片描述


解1:暴力求解,数组 + 两层for循环枚举,结果TLE。时间复杂度O(n²),n为106,运行次数为 1012>109

#include <cstdio>

int arr[1000010];  //申请全局数组,若在main函数内申请如此大的数组 会爆栈,即栈溢出(Segementation fault)

int main() {
    int n,x;
    scanf("%d",&n);
    scanf("%d",&x);
    for(int i = 0; i < n; ++i){
        scanf("%d",&arr[i]);
    }
    int count = 0;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            if(arr[i]-arr[j] == x)   count++;
        }
    }
    printf("%d\n",count);
    return 0;
}

解2:优化为用哈希表 unordered_map存储,时间复杂度O(n)

在这里插入代码片

TLE问题:处理大数据集的策略,降低算法的时间复杂度

①TLE (Time Limit Exceeded,时间超过)的限制是运行次数不超过 1 0 9 10^9 109
而对于数据规模n达到 1 0 6 10^6 106级别,时间复杂度最高只能为 O ( n l o g n ) O(nlogn) O(nlogn),若为 O ( n 2 ) O(n²) O(n2)则超时,运行了 1 0 12 10^{12} 1012次。
②若申请动态数组还是 TLE,则只能优化算法,不能暴力求解,如m层for循环枚举的时间复杂度为 O ( n m ) O(n^m) O(nm)
应当思考如何优化算法 以降低算法的时间复杂度,减少 不必要的计算 或 重复计算,如 缩小搜索范围、用数组存储会重复使用到的数值。



第4章 字符串

1.C字符数组 char str[1000] :处理输入、输出

(1)原理

1.char的C风格字符数组,每个单元只能存储1个字符

2.C风格字符串,要多一个字节存储 终止符 '\0'

在这里插入图片描述
在这里插入图片描述

区分:
①可打印字符 '0'
②终止符 0'\0'


(2)基本操作

1.声明: char 字符数组名[大小];

2.初始化:直接赋值0,或用memset

char str[1000] = {0};
#include <cstring>

char str[1000];
memset(str,0,sizeof(str));

3.输入
字符数组的输入可以省略&。因为数组名本身就是一个地址,不需要再取地址

scanf("%s",str);

4.输出

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

5.字符数组转string:string 字符串名 = 字符数组名 ;

步骤:
①先声明字符数组
②字符数组操作,如输入
③转string string 字符串名 = 字符数组名 ;
④字符串操作
⑤输出 printf("%s",字符串名.c_str());

注意,只有%s的时候输出string需要加 .c_str()转换。而%c的时候可以直接输出str[i]

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

int main(){
	char buf[100];
	scanf("%s",buf);//%s不用加&
	string str = buf;//C风格字符数组 → C++风格字符串:直接赋值
	printf("%s\n",str.c_str());//C++风格字符串→C风格字符数组:.c_str()

	return 0;
}

6.读取一整行
fgets(字符数组名,sizeof(字符数组名),stdin)

fgets最后会读入换行符\n ,占一个空间(字符数组转string后,考虑用pop_back()干掉回车)
在这里插入图片描述

7.getchar() 吃掉回车



(2)优势与劣势

①C风格字符数组:char str[100]

1.C风格字符数组的优势:可以直接使用scanf和printf

2.C风格字符数组的劣势:
①不支持 赋值、相等判断、比大小
②不支持 提取子串、字符串匹配
③C风格字符串不能作为map和set的参数
④内存管理麻烦 (数组与指针的转换)


②C++字符串:string

1.string的优势:
①像内置类型 (int/long/float/double),支持 +、=、==、<、<=、>、>=

②类似于 vector<char>,支持 push_back()、insert、erase、clear、迭代器、方括号运算符

③支持子串操作:求子串 substr()、字符串匹配


2.string的缺陷:
string不能直接和printf、scanf交互



2.C++ 字符串string :处理更复杂问题

(1)基本操作

1.头文件

#include <string>
using namespace std;

2.初始化:支持 = 赋值操作

string str1 = "hello";
string str2 = str1;

3.求长度:
.length();
.size();

printf("length of str = %u\n",str.size());

(2)增删改查遍历

1.遍历
(1)方括号运算符:
下标访问元素:str[i](i从0开始)

for(unsigned int i = 0;i < str.size(); ++i){
	printf("%c\n",str[i]);
}

(2)迭代器:

for(string::iterator it = str.beign(); it != str.end(); ++it){
	//++it 更改迭代器的指向,到下一个元素
	printf("%c\n", *it); // &取地址, *取内容。*it 通过地址访问元素
}

string 对比 vector<char> 拓展了insert 和 erase 的用法,可以一次操作多个字符


2.插入:
(1)末尾插入:push_back(n)

(2)指定位置插入:

insert(it,"A");  //迭代器插入
insert(0,"xyz"); //指定下标插入,可以一次操作插入多个字符

3.删除:
(1)删除最后一个字符:pop_back()

(2)字符串清空 clear()

str.clear();

(3)指定位置删除:erase(下标)

str.erase(str.size()-1); //删除最后一个元素,即\n
str.erase(it); //迭代器指定位置

①删除position处的一个字符(position是个string类型的迭代器)
erase(position);

②删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
erase(pos,n);

string str = "abcdef";
str.erase(1,2); //从下标1开始,删除2个,应该删除bc

③删除从first到last之间的字符(first和last都是迭代器)
erase(first,last);


(4)按照元素删除:删除指定字符
如:删除字符串a中的的逗号

string str;
string::iterator it;
for(it=str.begin();it!=str.end();++it){
    if(*it == ','){
        str.erase(it);
    }
}

4.查找:字符串匹配
find("字符串内容")
find("字符串内容",起始下标)

返回值是第一次匹配成功的下标。若查找失败,则返回string::npos,即-1

int pos = str.find("do"); //查找匹配字符串do,不写起始下标,默认为从开始
if(pos == string::npos)    printf("do is not found!\n");

查找:
查询字符或字符子串的下标 .find(内容)
find("字符串")
find(变量名)
在这里插入图片描述


用string的find函数进行字符串匹配的例题:CPP33 统计字符串中子串出现的次数

在这里插入图片描述

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

int main() {
    char str[100] = { 0 };
    char substr[100] = { 0 };

    cin.getline(str, sizeof(str));
    cin.getline(substr, sizeof(substr));

    int count = 0;

    // write your code here......
    string str1 = str;
    string str2 = substr;
    int pos = str1.find(str2);
    while(pos != string::npos){
        count++;
        pos = str1.find(str2,pos+1);
    }
	
    cout << count << endl;
    return 0;
}

(3)子串操作

1.从C++风格字符串转到C风格字符串:str1.c_str()


2.判断相等:支持==

bool isSame = false;
isSame = (str1 == "hello");

3.连接:
+ (只针对C++风格字符串string类型,C风格字符数组禁止相加)

string str = buf;
str = str + "world";

4.string比较大小:从最高位比ASCII码(字典序):

string str1 = "a";
string str2 = "Z";
if(str1<str2) cout<<str1<<"<"<<str2<<endl;
else          cout<<str1<<">="<<str2<<endl;

输出:a>=Z


ASCII码
原因:
①A的ASCII码为65,Z的ASCII码为90
②a的ASCII码为97,z的ASCII码为122
③大写字母 +32 = 小写字母
小写字母 -32 = 大写字母

if(arr[i]>='A' && arr[i]<="Z")	arr[i] += 32; //大写转小写
if(str[i]>='a' && str[i]<='z')	str[i] -= 32; //小写转大写

在这里插入图片描述


5.string支持方括号运算符,支持下标访问

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

int main() {
    string str = "abcdef";
    char ch[26];
    for(int i = 0; i <str.size(); ++i){
        ch[i] = str[i];
    }
    for(int i = 0; i <strlen(ch); ++i){
        cout<<"ch["<<i<<"] = "<<ch[i]<<endl;
    }
    return 0;
}

输出:
ch[0] = a
ch[1] = b
ch[2] = c
ch[3] = d
ch[4] = e
ch[5] = f


6.取子串
(1)从起始下标到字符串结尾
substr(起始下标)

(2)从指定下标开始,截取指定长度
substr(起始下标,截取的长度)

string str2 = str1.substr(0,3);  //从0开始,长度为3 

(4)其他操作

1.string和数值相互转换

在这里插入图片描述

int i = 1234;
string str1 = to_string(i);

float f = 3.14;
string str2 = to_string(f);
string str1 = "3.1415";
f = stof(str1);

string str2 = "31415";
i = stoi(str2);

在这里插入图片描述


2.string的输入输出

1.输入

char arr[100];
scanf("%s",arr); //先读到字符数组
string str = arr;   //再转成string

2.输出
(1)printf 的 c_str()
在这里插入图片描述


(2)cin 和 cout
cin 和 cout,不能和 scanf、printf 混用

在这里插入图片描述


3.一次读入一行
(1)C语言:fgets()

1.C语言用fgets()读入一整行的内容,包括换行符 \n

2.fgets(字符数组首地址,申请内存的长度,stdin);

fgets(arr,200,stdin);

(2)C++:cin.getline()
char str[100] = { 0 };
char substr[100] = { 0 };

cin.getline(str, sizeof(str));
cin.getline(substr, sizeof(substr));



3.例题

例题1:单词个数统计 (难度:中等)

提交网址:https://www.acwing.com/problem/content/3618/

在这里插入图片描述
在这里插入图片描述

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

int main(){
    string s;
    getline(cin,s);
    int count_letter = 0,count_word = 1; //最后一个单词没有空格
    map<char,int> mymap;  //用 map<char,int> 统计字母出现次数
    for(int i = 0; i < s.size(); ++i){
        //1.统计字母个数
        if((s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<='Z') ){
            count_letter++;
        }
        //2.统计单词个数
        if(s[i] == ' ' && s[i+1] != ' '){
            count_word++;
        }
        //3.统计出现次数最多的字母 (不区分大小写,全部以小写为主)
        if((s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<='Z') ){
            if(s[i]>='A' && s[i]<='Z'){
                s[i] = s[i]+32;  //大写转小写
            }
            mymap[s[i]]++;
        }
    }
    cout << count_letter << endl << count_word << endl;
    int max = 0; //字母出现次数的最大值
    map<char,int>::iterator it;
    for(it = mymap.begin(); it != mymap.end(); ++it){
        if(it->second > max)    max = it->second;
    }
    for(it = mymap.begin(); it != mymap.end(); ++it){
        if(it->second == max){
            cout << it->first << " ";
        }
    }
    cout << endl << max << endl;
    return 0;
}

例题2:浮点数加法 【高精度运算】(难度:Mid-Hard)

提交网址:http://t.cn/Ai8I4v0j
在这里插入图片描述

高精度运算:用字符串,模拟竖式运算

王道《上机指南》 2024炉灰老师的解法:(这是我做过的代码最多的一道题,93行。当然整数相加部分的if、else if有很多近似重复代码)

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

//获取整数部分
string GetInterger(string a){
    return a.substr(0,a.find('.'));
}

//获取小数部分
string GetFraction(string a){
    return a.substr(a.find('.')+1);
}

//小数部分相加
void FractionPlus(string &res,int &carry,string fa,string fb){
    //长度短的小数,补0
    int size = max(fa.size(),fb.size());
    while(fa.size() < size){
        fa.push_back('0');
    }
    while(fb.size() < size){
        fb.push_back('0');
    }
//    cout << "fa = " << fa << endl << "fb = " << fb << endl;
    res.resize(size); //给res申请内存空间
    for(int i = size-1; i >= 0; --i){  //从右向左遍历
        if(fa[i] + fb[i] + carry - '0' > '9'){
            res[i] = fa[i] + fb[i] + carry - '0' - 10;
            carry = 1;
        }else{
            res[i] = fa[i] + fb[i] +carry - '0';
            carry = 0;
        }
    }
//    cout << "fres= " << res << endl << "carry = " << carry << endl;
}

//整数部分相加
void IntegerPlus(string &res, int carry,string ia,string ib){
    res.clear();
    for(int i = ia.size()-1,j = ib.size()-1; i >= 0 || j >= 0 || carry == 1; --i,--j){
        if(i >= 0 && j >= 0){  //1.a和b都有
            if(ia[i] + ib[j] + carry - '0' > '9'){
                res.insert(res.begin(),ia[i] + ib[j] + carry - '0' - 10);
                carry = 1;
            }else{
                res.insert(res.begin(),ia[i] + ib[j] + carry - '0');
                carry = 0;
            }
        }else if(i >= 0 && j < 0){   //2.只有a
            if(ia[i] + carry > '9'){
                res.insert(res.begin(),ia[i] + carry - 10);
                carry = 1;
            }else{
                res.insert(res.begin(),ia[i] + carry);
                carry = 0;
            }
        }else if(i < 0 && j >= 0){   //3.只有b
            if(ib[j] + carry > '9'){
                res.insert(res.begin(),ib[j] + carry - 10);
                carry = 1;
            }else{
                res.insert(res.begin(),ib[j] + carry);
                carry = 0;
            }
        }else{  //4.既没有a,也没有b,只有进位 carry=1
            res.insert(res.begin(),'1');
            carry = 0;
        }
    }
//    cout << "ires= " << res << endl << "carry = " << carry << endl;
}

int main() {
    string a,b;
    cin >> a >> b;
//    a = "12345.6789";
//    b = "333.33333";
    string ia,fa,ib,fb;
    ia = GetInterger(a);
    fa = GetFraction(a);
    ib = GetInterger(b);
    fb = GetFraction(b);
//    cout << "ia = " <<ia << endl << "fa = " << fa << endl << "ib = " << ib << endl << "fb = " << fb << endl << endl;
    string fres;
    int carry = 0;
    FractionPlus(fres,carry,fa,fb);
    string ires;
    IntegerPlus(ires,carry,ia,ib);
    cout << ires << "." << fres << endl;
    return 0;
}

例题3:W的密码 (难度:困难)

提交网址:https://www.acwing.com/problem/content/3408/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

void Partition(string str,vector<int> &vec1,vector<int> &vec2,vector<int> &vec3){
    int i;
    for(i = 0; i < str.size(); ++i){
        if(str[i] >= 'a' && str[i] <= 'i'){
            vec1.push_back(i);
        }else if(str[i] >= 'j' && str[i] <= 'r'){
            vec2.push_back(i);
        }else{
            vec3.push_back(i);
        }
    }
}

//右旋
void RightRotate(string &str, vector<int> &vec, int offset){
    vector<char> tmp;
    if (vec.size() != 0 && offset > vec.size()) {
        offset = offset % vec.size();
    }
    for(int i = vec.size() - offset; i < vec.size(); ++i){
        tmp.push_back(str[vec[i]]);
    }
    for(int i = vec.size() - offset - 1; i >= 0; --i){
        str[vec[i+ offset]]  = str[vec[i]];
    }
    for(int i = 0; i < tmp.size(); ++i){
        str[vec[i]] = tmp[i];
    }
}

int main() {
//    string str = "_icuo_bfnwhoq_kxert";
//    int k1 = 2, k2 = 3, k3 = 1;
    string str;
    int k1,k2,k3;
    while(cin >> k1 >> k2 >> k3){
        if(k1==0 && k2==0 && k3==0)  break;
        cin >> str;
        vector<int> vec1, vec2, vec3;
        Partition(str,vec1,vec2,vec3);
        RightRotate(str,vec1,k1);
        RightRotate(str,vec2,k2);
        RightRotate(str,vec3,k3);
        cout << str << endl;
    }
    return 0;
}

4.习题

习题1:统计字符串中各类型字符的个数 (难度:入门)

提交网址:https://www.nowcoder.com/share/jump/2891302591707795122907

在这里插入图片描述

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

int main() {
    int letter = 0;
    int digit = 0;
    int space = 0;
    int other = 0;
    
    char buf[1024] = {0};
    cin.getline(buf, sizeof(buf));
    // write your code here......
    for(int i = 0; buf[i] != '\0'; ++i){
        if((buf[i]>='A' && buf[i]<='Z') || (buf[i]>='a' && buf[i]<='z')) letter++;
        else if( buf[i]>='0' && buf[i]<='9' )   digit++;
        else if(buf[i]==' ')    space++;
        else                    other++;
    } 
    //end   
    cout << "letter:" << letter << " digit:" << digit << " space:"
    	 << space << " other:" << other << endl;
    return 0;
}

习题2:大写字母个数统计 (难度:入门)

提交网址:http://t.cn/Ai8VB72e

在这里插入图片描述

次数为0的字母也要统计,所以本题不可用 map<char,int>,可以用一个int数组统计各字母出现的次数

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

int main() {
    string str;
    getline(cin,str);
    int count[26] = {0};
    for(int i = 0; i < str.size(); ++i){
        if(str[i]>='A' && str[i]<='Z'){
            count[str[i]-'A']++;
        }
    }
    for(int i = 0; i < 26; ++i){
        printf("%c:%d\n",'A'+i,count[i]);
    }
    return 0;
}

习题3:首字母大写 (难度:简单)

提交网址:https://www.nowcoder.com/share/jump/2891302591707807598497

在这里插入图片描述

用getline(cin,str)读入一行。用空白符分割单词,判断是否为单词的首字母

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

int main(){
    string str;
    while(getline(cin,str)){
        //首字母小写转大写
        if(str[0]>='a' && str[0]<='z')  str[0] = str[0]- 32;
        cout<<str[0];
        //保持空白符不变
        for(int i = 1; i < str.size(); i++){
            if(str[i]==' ' || str[i]=='\t' || str[i]=='\r' || str[i]=='\n' ){
                if(str[i+1]>='a' && str[i+1]<='z'){
                    str[i+1] -= 32; //空白符后的单词首字母大写
                } 
            }
            cout<<str[i];
        }
    }
    return 0;
}

习题4:寻找变化前的01序列 【字符串替换】 (难度:简单)

提交网址:https://www.acwing.com/problem/content/3547/

在这里插入图片描述


解法1:
用count统计连续出现的1的个数,当count为5时就屏蔽输出下一个字符(一定是0)

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

int main() {
    int n;
    cin >> n;
    while(n--){
        string str;
        cin >> str;
        int count = 0;
        for(int i = 0; i < str.size(); ++i){
            if(str[i] == '1'){
                count++;
                cout << str[i];
            }else{
                if(count==5){
                    count = 0;
                    continue; //不输出字符0,直接检查下一个字符
                }
                cout<<str[i];
                count = 0;
            }
        }
        cout << endl;
    }
    return 0;
}

解法2:replace()函数

# include <iostream>

using namespace std;
int T;
string s;
const string find_one = "111110";
const string change_one = "11111";
int main()
{
    //cin.sync_with_stdio(false);
    cin >> T;
    for(size_t _ = 0; _ != T; _++)
    {
        cin >> s;
        size_t place = 0;
        place = s.find(find_one , place);
        for(; place != string::npos && place < s.length(); 
        s.replace(place , 6 , change_one) , place += 5 , 
        place = s.find(find_one , place)) ;// 111110长度6

        cout << s << '\n';
    }
    return 0;
}

习题5:大整数排序 (难度:简单)

提交网址:https://www.acwing.com/problem/content/3611/

在这里插入图片描述

思路:借用vector的自动排序功能,对sort函数添加上comp中按字符串长度升序排序,长度相等时按a<b字典序排序。关键在于comp函数的构建

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

bool comp(string a,string b){
    if(a.size() < b.size())       return true;
    else if(a.size() > b.size())  return false;
    else                          return a<b;
}

int main() {
    int n;
    cin >> n;
    string s;
    vector<string> vec;
    for(int i = 0; i < n; i++){
        cin >> s;
        vec.push_back(s);
    }
    sort(vec.begin(),vec.end(),comp);
    vector<string>::iterator it;
    for(it = vec.begin(); it != vec.end(); ++it){
        cout << *it << endl;
    }
    return 0;
}

习题6:单词替换 【字符串替换】(难度:中等)

提交网址:http://t.cn/Ai8Iycp6

在这里插入图片描述

字符串替换,用vector<string>

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

int main(){
    //1.读入一整行
    string s,a,b;
    getline(cin,s); 
    cin >> a >> b;
    //2.分割单词,存入vector
    vector<string> vec;
    string sub = ""; //子串,初始为空
    for(int i = 0 ; i < s.size(); ++i){
        if(s[i] != ' '){
            sub = sub + s[i];
        }else{
            vec.push_back(sub);
            sub.clear();
        }
        if(i == s.size()-1){  //存入最后一个单词
            vec.push_back(sub);
            sub.clear();
        }
    }
    //3.替换
    for(int i = 0; i < vec.size(); ++i){
        if(vec[i] == a){
            vec[i] = b;
        }
    }
    //4.遍历输出
    vector<string>::iterator it;
    for(it = vec.begin(); it != vec.end(); ++it){
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}

习题7:skew数 【进制转换】(难度:)

提交网址:http://t.cn/Ai8IALKI
在这里插入图片描述
在这里插入图片描述


习题8:复制、剪切、粘贴 (难度:)

提交网址:https://www.acwing.com/problem/content/3549/

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/397689.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

N5182A MXG 矢量信号发生器,100 kHz 至 6 GHz

N5182A MXG 矢量信号发生器 简述&#xff1a; Agilent N5182A 具有快速频率、幅度和波形切换、带有电子衰减器的高功率和高可靠性——所有这些都在两个机架单元 (2RU) 中。安捷伦 MXG 矢量针对制造蜂窝通信和无线连接组件进行了优化。安捷伦 MXG 矢量通过增加吞吐量、提高测试良…

C++11---(3)

目录 一、可变参数模板 1.1、可变参数模板的概念 1.2、可变参数模板的定义方式 1.3、如何获取可变参数 二、lambda表达式 2.1、Lamabda表达式定义 2.2、为什么有Lambda 2.3、Lambda表达式的用法 2.4、函数对象与lambda表达式 三、包装器 3.1、function 3.2、bind …

SORA大模型的一点分析与理解

Overview SORA一、原始技术博客分析1、Overview2、视频生成相关工作3、Turning visual data into patches4、Video compression network5、Spacetime latent patches6、Scaling transformers for video generation7、Variable durations, resolutions, aspect ratios8、Languag…

实现VLAN间通信以太网链路聚合与交换机堆叠、集群华为ICT网络赛道

10.实现VLAN间通信 10.1.使用路由器实现VLAN间通信 使用路由器物理接口 路由器三层接口作为网关&#xff0c;转发本网段前往其它网段的流量。 路由器三层接口无法处理携带VLAN Tag的数据帧&#xff0c;因此交换机上联路由器的接口需配置为Access. 路由器的一个物理接口作为一…

数据分析案例-2023年TOP100国外电影数据可视化

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

vue3 之 商城项目—会员中心

整体功能梳理 1️⃣个人中心—个人信息和猜你喜欢数据渲染 2️⃣我的订单—各种状态下的订单列表展示 路由配置&#xff08;三级路由配置&#xff09; 准备模版member/index.vue <script setup> </script><template><div class"container">…

redis分布式锁redisson

文章目录 1. 分布式锁1.1 基本原理和实现方式对比synchronized锁在集群模式下的问题多jvm使用同一个锁监视器分布式锁概念分布式锁须满足的条件分布式锁的实现 1.2 基于Redis的分布式锁获取锁&释放锁操作示例 基于Redis实现分布式锁初级版本ILock接口SimpleRedisLock使用示…

条码扫描器

介绍 条码扫描器&#xff0c;又称为条码阅读器、条码扫描枪、条形码扫描器、条形码扫描枪及条形码阅读器。它是用于读取条码所包含信息的阅读设备&#xff0c;利用光学原理&#xff0c;把条形码的内容解码后通过数据线或者无线的方式传输到电脑或者别的设备。广泛应用于超市、物…

idea代码review工具Code Review Helper使用介绍

之前在团队里面遇到一个关于代码review的问题&#xff0c;使用gitlab自己的还是facebook的Phabricator&#xff0c;很难看到整体逻辑&#xff0c;因为业务逻辑代码可能不在这次改动范围内&#xff0c;在去源库中找不好找。针对这个刚需&#xff0c;在网上找了一个idea的代码工具…

区块链革命:Web3如何改变我们的生活

随着技术的不断发展&#xff0c;区块链技术作为一种去中心化的分布式账本技术&#xff0c;正逐渐成为数字世界的核心。Web3作为区块链技术的重要组成部分&#xff0c;正在引领着数字化时代的变革&#xff0c;其影响已经开始渗透到我们生活的方方面面。本文将深入探讨区块链革命…

ALBEF算法解读

ALBEF论文全名Align before Fuse: Vision and Language Representation Learning with Momentum Distillation&#xff0c;来自于Align before Fuse&#xff0c;作者团队为Salesforce Research。 论文地址&#xff1a;https://arxiv.org/pdf/2107.07651.pdf 论文代码&#xff1…

SICTF round#3 web

1.100&#xff05;_upload url可以进行文件包含&#xff0c;但是flag被过滤 看一下源码 <?phpif(isset($_FILES[upfile])){$uploaddir uploads/;$uploadfile $uploaddir . basename($_FILES[upfile][name]);$ext pathinfo($_FILES[upfile][name],PATHINFO_EXTENSION);$t…

大模型量化技术原理-LLM.int8()、GPTQ

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;从而导致模型变得越来越大&#xff0c;因此&#xff0c;我们需要一些大模型压缩技术来降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型压缩主要分…

react开发者必备vscode插件【2024最新】

React开发者必备VSCode插件及使用教程 Visual Studio Code&#xff08;VSCode&#xff09;是当今最流行的代码编辑器之一&#xff0c;特别是在前端开发者中。对于使用React的开发者来说&#xff0c;VSCode不仅因其轻量和高度可定制而受到欢迎&#xff0c;还因为其强大的插件生…

Java项目,营销抽奖系统设计实现

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 项目&#xff1a;https://gaga.plus 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 大家好&#xff0c;我是技术UP主&#xff0c;小傅哥。 经过这个假期的嘎嘎卷&#x1f9e8;…

8 大内部排序算法图文讲解

排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。常见的内部排序算法有&#xff1a;插入排序、希尔排序、选择排序…

软件测试面试题常见一百道【含答案】

1、问&#xff1a;你在测试中发现了一个bug&#xff0c;但是开发经理认为这不是一个bug&#xff0c;你应该怎样解决? 首先&#xff0c;将问题提交到缺陷管理库里面进行备案。 然后&#xff0c;要获取判断的依据和标准&#xff1a; 根据需求说明书、产品说明、设计文档等&am…

75.SpringMVC的拦截器和过滤器有什么区别?执行顺序?

75.SpringMVC的拦截器和过滤器有什么区别&#xff1f;执行顺序&#xff1f; 区别 拦截器不依赖与servlet容器&#xff0c;过滤器依赖与servlet容器。拦截器只能对action请求(DispatcherServlet 映射的请求)起作用&#xff0c;而过滤器则可以对几乎所有的请求起作用。拦截器可…

Redis基础和高级使用

文章目录 Redis概述Redis简介Redis特点Redis适合于做Redis不适合于做Redis安装 Redis命令Redis命令Redis的键 Redis数据类型Redis支持的数据类型字符串及相关命令字符串应用场景&#xff1a;列表及相关命令列表应用场景&#xff1a;集合及相关命令集合应用场景&#xff1a;有序…

环信IM Android端实现华为推送详细步骤

首先我们要参照华为的官网去完成 &#xff0c;以下两个配置都是华为文档为我们提供的 1.https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/android-config-agc-0000001050170137#section19884105518498 2.https://developer.huawei.com/consumer/cn/doc/HMSCore…