当前位置: 首页 > news >正文

PAT乙级真题 / 知识点(2)

引言:

引言,可能是写给别人看的,也可能是写给那个不远后回顾的这里的自己

我被牛客的50元代金卷,骗到了那里刷题....

哈哈其实也没啥讨厌的,虽然没拿到钱,但是学到了新知识,看到了"基础算法"这条路上,不一样的风景!

查漏补缺-数组初始化、进制转化、string运用、链表表示、scanf与printf搭配解决时间问题、公式模拟、思维锻炼、枝剪操作、刷新对<cmath><algorithm><cctype>的认识。

挺开心的Ψ( ̄∀ ̄)Ψ

!!但是被牛客的代金卷骗了还是很不爽!本来想凭实力挣钱,最后还是被破无奈的....

于是机智的我,就去闲鱼上买了一张80元的代金卷( ̄︶ ̄)↗ 区区小难怎么能难得倒小爷我

大纲:

1021、个位数统计(15)(解析)- 数组初始化方法,简单题写成难题,哭晕在厕所里

1022、D进制的A+B(20)(解析)- 模拟题,进制转化

1023、组个最小数(20)(解析)- to_string()的运用时刻

1024、科学计数法(20)(解析)- 极致锻炼对string的控制力度

1025、反转链表(25)(解析)- 链表与2个数组结合data[n],next[n],柳神是我女神

1026、程序运行时间(15)(解析)- 优美的时间输入输出scanf与printf搭配

1027、打印沙漏(20)(解析)- 公式模拟

1028、人口普查(20)- (解析)字符串比大小

1029、旧键盘(20)- (解析)string中的find查找,与string::npos

1030、完美数列(25)- (解析)思维漏洞

题目:

1021、个位数统计(15)

给定一个 k 位整数 N=dk−1​10k−1+⋯+d1​101+d0​ (0≤di​≤9, i=0,⋯,k−1, dk−1​>0),请编写程序统计每种不同的个位数字出现的次数。例如:给定 N=100311,则有 2 个 0,3 个 1,和 1 个 3。

输入格式:

每个输入包含 1 个测试用例,即一个不超过 1000 位的正整数 N。

输出格式:

对 N 中每一种不同的个位数字,以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升序输出。

输入样例:

100311

输出样例:

0:2
1:3
3:1
// 哭晕在厕所里,这么简单的一道题,为啥我要用这么复杂的方法,掌握数组初始化的方法
#include <iostream>
using namespace std;
int main(){
    int arr[10] = {0};  // 部分初始化
    string str;
    cin>>str;
    for(char c : str)
        arr[c-'0']++;
    for(int i=0; i<10; ++i)
        if(arr[i]!=0)
            cout<<i<<":"<<arr[i]<<endl;
    return 0;
}

/*
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// vec初始化与push_back同时使用出错,第一次主动运用struct并正确,char与int转化

struct num{
    char N;
    int M;
};
static bool cmp(num n1, num n2){
    return n1.N<n2.N;
}
int main(){
    // 用结构体试试
    string str;
    cin>>str;
    vector<num> vec;
    for(int i=0; i<10; ++i) // 这样行吗??没有试过
        vec.push_back(num{(char)(i+'0'),0});
    for(char c : str){
        vec[c-'0'].M++;
    }
    sort(vec.begin(),vec.end(),cmp);
    for(int i=0; i<10; ++i){
        if(vec[i].M!=0){
            cout<<i<<":"<<vec[i].M<<endl;
        }
    }
    return 0;
}
*/

1022、D进制的A+B(20)

输入两个非负 10 进制整数 A 和 B (≤230−1),输出 A+B 的 D (1<D≤10)进制数。

输入格式:

输入在一行中依次给出 3 个整数 A、B 和 D。

输出格式:

输出 A+B 的 D 进制数。

输入样例:

123 456 8

输出样例:

1103
#include <iostream>
#include <algorithm> // 忘了,但是为啥还能对!
#define ll long long
using namespace std;
// 本题是一道简单的进制转换模拟题
int main(){
    ll a,b,d;
    cin>>a>>b>>d;
    a+=b; // 将a设为总和
    string str = "";
    while(1){
        if(a<d){
            str += to_string(a);
            break;
        }
        str += to_string(a%d);
        a = a/d;
    }
    reverse(str.begin(),str.end());
    cout<<str<<endl;
    return 0;
}

1023、组个最小数(20)

给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就是 10015558。

现给定数字,请编写程序输出能够组成的最小的数。

输入格式:

输入在一行中给出 10 个非负整数,顺序表示我们拥有数字 0、数字 1、……数字 9 的个数。整数间用一个空格分隔。10 个数字的总个数不超过 50,且至少拥有 1 个非 0 的数字。

输出格式:

在一行中输出能够组成的最小的数。

输入样例:

2 2 0 0 0 3 0 0 1 0

输出样例:

10015558
#include <iostream>
#include <algorithm>
using namespace std;
// 若看不清题,能气死人,数字要用to_string()进行转换成字符串
int main(){
    int arr[10];
    for(int i=0; i<10; ++i)
        cin>>arr[i];     
    int num=0;
    string str = "";
    for(int i=0; i<10; ++i){
        for(int j=0; j<arr[i]; ++j){
            if(i!=0&&num==0) num=i;
            else str+=to_string(i);
        }
    }
    if(num!=0) str = to_string(num) + str;
    cout<<str<<endl;
    return 0;
}

1024、科学计数法(20)

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。

现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。

输入格式:

每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。

输出格式:

对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。

输入样例 1:

+1.23400E-03

输出样例 1:

0.00123400

输入样例 2:

-1.2E+10

输出样例 2:

-12000000000
#include <iostream>
#include <cmath>
using namespace std;
// 这道题目,可以好好练练
// 极致锻炼对string的控制力度
int main(){
    // 好好分析每一步骤
    string str,n,m; // n(E前),m(E后)
    cin>>str;
    // 获取代码大小
    int e = 0;
    while(str[++e]!='E');
    n = str.substr(1,e-1); // E前
    m = str.substr(e+1); // E后
    if(str[0]=='-') cout<<"-";
    int num = stoi(m);
    if(num<0){ // 向前移动
        cout<<"0.";
        for(int i=0; i<fabs(num)-1; ++i) cout<<"0";
        for(int i=0; i<n.size(); ++i)
            if(n[i]!='.') cout<<n[i];
    } else { // 向后移动
        cout<<n[0];
        int j,cur;
        for(j=2,cur=0; j<n.size()&&cur<fabs(num); ++j,++cur)  cout<<n[j];
        if(j==n.size()){
            for(; cur<fabs(num); ++cur) cout<<0;
        }else {
            cout<<".";
            for(; j<n.size(); ++j) cout<<n[j];
        }
    }
    
    
    return 0;
}

1025、反转链表(25)

给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转。例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4;如果 K 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 K 个元素不反转。

输入格式:

每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤105)、以及正整数 K (≤N),即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。

接下来有 N 行,每行格式为:

Address Data Next

其中 Address 是结点地址,Data 是该结点保存的整数数据,Next 是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

输出样例:

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include <iostream>
#include <algorithm>
using namespace std;
// 其实,这道题,我看了柳神的代码,最开始是不理解的,问了deepseek
int main(){
    // 本题,如果单纯要反置链表的是很难的,但是取巧不难
    int start,n,k; // start(首节点) n(节点总个数) k(翻转个数)
    cin>>start>>n>>k;
    int data[100005],next[100005],list[100005]; // 用两个数组来储存
    while(n--){
        int temp;
        cin>>temp; 
        cin>>data[temp]>>next[temp];
    }
    int sum = 0;
    while(start!=-1){
        list[sum++]=start;
        start = next[start];
    }
    list[sum]=-1;
    for(int i=0; i<(sum-sum%k); i+=k){ // 简直优雅的像一只天鹅🦢,sum是从0开始的,对于其他非常OK的!
        reverse(list+i,list+i+k);
    }
    for(int i=0; i<sum-1; ++i) // 末尾那个为空
        printf("%05d %d %05d\n",list[i],data[list[i]],list[i+1]);
    printf("%05d %d %d\n",list[sum-1],data[list[sum-1]],list[sum]);
    return 0;
}

1026、程序运行时间(15)

要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间单位是 clock tick,即“时钟打点”。同时还有一个常数 CLK_TCK,给出了机器时钟每秒所走的时钟打点数。于是为了获得一个函数 f 的运行时间,我们只要在调用 f 之前先调用 clock(),获得一个时钟打点数 C1;在 f 执行完成后再调用 clock(),获得另一个时钟打点数 C2;两次获得的时钟打点数之差 (C2-C1) 就是 f 运行所消耗的时钟打点数,再除以常数 CLK_TCK,就得到了以秒为单位的运行时间。

这里不妨简单假设常数 CLK_TCK 为 100。现给定被测函数前后两次获得的时钟打点数,请你给出被测函数运行的时间。

输入格式:

输入在一行中顺序给出 2 个整数 C1 和 C2。注意两次获得的时钟打点数肯定不相同,即 C1 < C2,并且取值在 [0,107]。

输出格式:

在一行中输出被测函数运行的时间。运行时间必须按照 hh:mm:ss(即2位的 时:分:秒)格式输出;不足 1 秒的时间四舍五入到秒。

输入样例:

123 4577973

输出样例:

12:42:59
#include <iostream>
#include <cmath>
using namespace std;
// 是一道简单题,优美的输入输出方法
int main(){
    int c1,c2;
    scanf("%d %d",&c1,&c2);
    int c = round((double)(c2-c1)/100);
    int hh,mm,ss;
    hh = c/3600;
    mm = c%3600/60;
    ss = c%60;
    printf("%02d:%02d:%02d",hh,mm,ss);
    return 0;
}

1027、打印沙漏(20)

本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

*****
 ***
  *
 ***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入格式:

输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。

输出格式:

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。

输入样例:

19 *

输出样例:

*****
 ***
  *
 ***
*****
2
#include <iostream>
using namespace std;
// 本题考查的就是一个公式模拟题
// 逆天,count没有初始化,忙活了半天
// 将中间的一个1减去。(3 5 7 9 ... 2i+1)= (3+2i+1)*i/2 = i*(i+2) // 代表上方个数
int main(){
    int n,count=0; // n(个数) count(层数)
    char c;
    cin>>n>>c;
    for(int i=0; i<n; ++i) // 求层数
        if(i*(i+2)*2+1>n){
            count = i-1;
            break;
        }

    for(int i=count; i>0; --i){ // 上方
        for(int j=0; j<count-i; ++j) cout<<" "; // 输出空格
        for(int j=0; j<(2*i+1); ++j) cout<<c;
        cout<<endl;
    }

    for(int j=0; j<count; ++j) cout<<" ";
    cout<<c<<endl;

    for(int i=1; i<=count; ++i){ // 下方
        for(int j=0; j<count-i; ++j) cout<<" "; // 输出空格
        for(int j=0; j<(2*i+1); ++j) cout<<c;
        cout<<endl;
    }

    cout<<n-(count*(count+2)*2+1)<<endl;
    return 0;
}

1028、人口普查(20)

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入格式:

输入在第一行给出正整数 N,取值在(0,105];随后 N 行,每行给出 1 个人的姓名(由不超过 5 个英文字母组成的字符串)、以及按 yyyy/mm/dd(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。

输出格式:

在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。

输入样例:

5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

输出样例:

3 Tom John
#include <iostream>
using namespace std;
// 讲究的是字符串的灵活运用 - 比教
int main(){
    int n;
    cin>>n;
    int num=0; 
    string timeMAX="2014/09/06",nameMax; // 年龄大
    string timeMIN="1814/09/06",nameMIN; // 年龄小
    string name,str;
    while(n--){
        cin>>name>>str;
        if(str>="1814/09/06"&&str<="2014/09/06"){ // 因为是逐个比较的
            num++;
            if(str<timeMAX){
                nameMax = name;
                timeMAX = str;
            } 
            if(str>timeMIN){
                nameMIN = name;
                timeMIN = str;
            }
        }
    }
    if(num!=0){
        cout<<num<<" "<<nameMax<<" "<<nameMIN;
    }else{
        cout<<0;
    }
    return 0;
}

/*
#include <iostream>
#include <vector>
#include <algorithm>
// 写复杂了,主要还是因为没见过这个!
using namespace std;
struct person {
    char name[6];
    int y, m, d;
};
bool cmp(const person& a, const person& b) {
    if (a.y != b.y) return a.y < b.y;
    if (a.m != b.m) return a.m < b.m;
    return a.d < b.d;
}
bool isValid(const person& p) {
    // Check lower bound (>= 1814/09/06)
    if (p.y < 1814) return false;
    if (p.y == 1814) {
        if (p.m < 9) return false;
        if (p.m == 9 && p.d < 6) return false;
    }
    // Check upper bound (<= 2014/09/06)
    if (p.y > 2014) return false;
    if (p.y == 2014) {
        if (p.m > 9) return false;
        if (p.m == 9 && p.d > 6) return false;
    }
    return true;
}
int main() {
    int n;
    cin >> n;
    vector<person> vec;
    while (n--) {
        person p;
        scanf("%s %d/%d/%d", p.name, &p.y, &p.m, &p.d);
        if (isValid(p)) {
            vec.push_back(p);
        }
    }
    sort(vec.begin(), vec.end(), cmp); // 确实是我考虑不周到
    if (vec.empty()) { // 没有吧空,给考虑进去
        printf("0\n");
    } else {
        printf("%ld %s %s\n", vec.size(), vec.front().name, vec.back().name);
    }
    return 0;
}
*/

1029、旧键盘(20)

旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。

输入格式:

输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过 80 个字符的串,由字母 A-Z(包括大、小写)、数字 0-9、以及下划线 _(代表空格)组成。题目保证 2 个字符串均非空。

输出格式:

按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有 1 个坏键。

输入样例:

7_This_is_a_test
_hs_s_a_es

输出样例:

7TI
#include <iostream>
using namespace std;
// string 的find查找string::npos
// C++中设置变量与初始化
// 哭死,柳姐总是,能将我这30行代码,浓缩成10行 ≧﹏≦ 哭泣,她简直太帅了
int main(){
    string str1,str2,ans="";
    cin>>str1>>str2;
    for(int i=0; i<str1.size(); ++i){
        if(str2.find(str1[i])==string::npos&&ans.find(toupper(str1[i]))==string::npos)
            ans+=toupper(str1[i]);
    }
    cout<<ans;
    return 0;   
}
/*
string get_str(string str){
    string str1="";
    for(int i=0; i<str.size(); ++i){
        if(str1.find(str[i])==string::npos){
            str1+=str[i];
        }
    }
    return str1;
}
string getUpString(string str){
    for(int i=0; i<str.size(); ++i)
        if(str[i]<='z'&&str[i]>='a') str[i]=(char)(str[i]+'A'-'a');
    return str;
}
int main(){
    string str1="",str2="";
    cin>>str1>>str2;
    str1=getUpString(str1);
    str2=getUpString(str2);
    string strDiff1="",strDiff2="";
    strDiff1 = get_str(str1);
    strDiff2 = get_str(str2);
    for(int i=0; i<strDiff1.size(); ++i){
        if(strDiff2.find(strDiff1[i])==string::npos){
            cout<<strDiff1[i];
        }
    } 
    return 0;
}
*/

1030、完美数列(25)

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。

现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。

输入格式:

输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数。第二行给出 N 个正整数,每个数不超过 109。

输出格式:

在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。

输入样例:

10 8
2 3 20 4 5 1 6 7 8 9

输出样例:

8
#include <iostream>
#include <algorithm>
using namespace std;
// 小心陷入::思维漏洞::,最大值能变,最小值当然也能变呀
int main(){
    int n;
    long long p;
    scanf("%d %lld",&n,&p);
    long long arr[n];
    for(int i=0; i<n; ++i) scanf("%lld",&arr[i]);
    sort(arr,arr+n); // 从小到大排序一下
    
    int count=0;
    long long sum;
    for(int i=0; i<n; ++i){ // 枝剪操作,可谓是淋漓尽致
        sum = arr[i]*p;
        int j;
        for(j=i+count; j<n ; ++j){
            if(arr[j]>sum) break;
        }
        count = max(count,j-i-1);
    }
    cout<<count+1<<endl;
    return 0;
}

拓展

一、数组初始化  ::(巩固基础)::

  1. 完整的初始化

  2. 部分初始化

  3. 默认初始化  -(全局 / 局部)

  4. 空初始化 - 运用{ }。

#include "iostream"
using namespace std;
int main(){

    int arr0[5] = {1,2,3,4,5}; // 完整初始化
    int arr1[10] = {1,2}; // 部分初始化,其他都为0
    for(int i:arr1) cout<<i<<" ";
    cout<<endl;
    cout<<"-------------------------"<<endl;

    // 全局变量,自动分配为0
    static int arr2[10] ;
    for(int i:arr2) cout<<i<<" ";
    cout<<endl;
    cout<<"-------------------------"<<endl;
    // 局部,则是随机
    int arr3[10]; // 默认初始化,随机分配
    for(int i:arr3) cout<<i<<endl;
    cout<<"-------------------------"<<endl;
    // {}带来的初始化
    int arr4[10]{}; // 空出初始化,但在C中是错误的!C++正确
    for(int i:arr4) cout<<i<<" ";
    cout<<endl;
    cout<<"-------------------------"<<endl;
    int arr5[10] = {}; // 这样也行
    for(int i:arr5) cout<<i<<" ";
    cout<<endl;
    cout<<"-------------------------"<<endl;
    return 0;
}


1 2 0 0 0 0 0 0 0 0 
-------------------------
0 0 0 0 0 0 0 0 0 0 
-------------------------
-1749481648
531
256
0
-1749481624
531
24
0
-199230992
61
-------------------------
0 0 0 0 0 0 0 0 0 0 
-------------------------
0 0 0 0 0 0 0 0 0 0 
-------------------------

二、<cmath>库 :: 基础学习 ::

  1. 向上、下取整、四舍五入、绝对值
  2. 指数、平方、开根
  3. 随机数
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(){

    // 整数变化
    round(3.1);
    cout<<round(3.1)<<endl; // round 是一个数学函数,用于将浮点数四舍五入到最接近的整数
    ceil(3.1); // 向上取整
    floor(3.2); // 向下取整
    int(3.3); // 取整数位

    log(1); // 取指数
    sqrt(4); // 平方根
    pow(2,3); // 结果为双精度,指数函数
    fabs(-3); // 取绝对值

    // 拓展
    srand((unsigned)time(NULL));
    for(int i = 0; i < 10;i++ ) // 随机数真奇怪,好像一切都是命中注定似的。
        cout << rand() << " ";
    return 0;
}

三、<algorithm>库  :: 基础学习 ::

  1. 排序(全部、部分)
  2. 搜索find
  3. 复制copy
  4. 比较equal
  5. 修改reverse
  6. 去排列next_permutation
  7. 归并merge
  8. 结合操作:并集、交集、差集
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
    vector<int> vec{6,4,1,3,2};
    // 部分排序算法 排序算法隐藏
    partial_sort(vec.begin(),vec.begin()+2,vec.end()); // 仅排序出前两个,其他不变
    for(int i:vec) cout<<i<<" ";

    // 搜索算法
    auto it = find(vec.begin(),vec.end(),3);
    if(it!=vec.end()) cout<<"存在"<<endl;

    // 复制算法你
    vector<int> vec2(5);
    copy(vec.begin(),vec.end(),vec2.begin());
    for(int i:vec2) cout<<i<<" ";

    // 比较函数
    cout<<"是否相同:"<<equal(vec.begin(),vec.end(),vec2.begin(),[](int a,int b){return a==b;})<<endl;

    // 修改算法
    reverse(vec.begin(),vec.end()); // 反转

    // 全排列算法
    do{
        for(int i:vec) cout<<i<<" ";
        cout<<endl;
    }while(next_permutation(vec.begin(),vec.end()));
    cout<<"OK"<<endl;

    // 归并算法
    vector<int> res(10); // 将两个有序区间,合并到一个区间内,记得哈!不有序
    merge(vec.begin(),vec.end(),vec2.begin(),vec2.end(),res.begin());
    for(int i : res) cout<<i<<" ";
    cout<<"OK"<< endl;

    // 集合算法
    vector<int> v1{1,2,34,5};
    vector<int> v2{3,2,34,15};
    vector<int> v3(v1.size()+v2.size());
    // 并集
    set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
    for(int i:v3) cout<<i<<" ";
    // 交集
    vector<int> v4(v1.size()+v2.size());
    set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v4.begin());
    // 差集
    // 第一个容器里面 减去第二个容器里面的数字
    vector<int> v5(v1.size()+v2.size());
    set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),v5.begin());


    return 0;
}

四、reverse  :: 基础巩固 ::

在C++中,reverse 是标准模板库(STL)提供的一个算法,用于反转指定范围内元素的顺序。以下是它的具体用法:

1. 概述

  • 函数原型reversestd 命名空间下的一个模板函数。

  • 头文件#include <algorithm>

template< class BidirectionalIterator >
void reverse( BidirectionalIterator first, BidirectionalIterator last );
  • 参数

    • first:指向要反转的范围的起始位置的双向迭代器。

    • last:指向要反转的范围的结束位置的双向迭代器(通常是一个指向结尾元素之后的位置的迭代器)。

2. 工作原理

  • reverse 会交换范围 [first, last) 内的元素,使其顺序反转。

  • 它不会修改任何指针或引用,只是交换元素的值。

  • 该算法适用于任何支持双向迭代器的容器(如 vectorlistdeque、C风格数组等)。

五、scanf读取字符串string  :: 基础巩固 ::

1. scanf 和 std::string 的问题

scanf 是 C 风格的输入函数,它需要一个字符数组(以 \0 结尾的字符串)作为参数。而 std::string 是 C++ 的字符串类型,它内部管理着一个动态分配的字符数组。直接将 std::string 的地址传递给 scanf 是不安全的,因为 scanf 并不知道 std::string 的内部实现细节。

2. 正确的用法

如果你坚持使用 scanf,可以先读取到一个字符数组,然后再将字符数组的内容赋值给 std::string。例如:

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

int main() {
    char buffer[100]; // 用于临时存储输入
    string name;

    // 使用 scanf 读取名字
    scanf("%s", buffer);

    // 将字符数组赋值给 std::string
    name = buffer;

    cout << "Name: " << name << endl;

    return 0;
}

3. 推荐使用 std::cin。

4. 总结

  • scanf 的限制scanf 可以读取字符串,但需要使用字符数组作为中间存储,不直接支持 std::string

  • 推荐使用 std::cinstd::cin 更安全、更易于使用,直接支持 std::string,并且可以处理包含空格的字符串。

  六、<cctype> :: 基础学习 ::

  1. 转大写(toupper)、转小写(tolower)
  2. 判断大写(isupper)、小写(islower)、数字(isdigit)、空格(isspace)
#include <iostream>
using namespace std;
int main(){
    cout<<toupper('a')<<tolower('A'); // 分别转化为大写、小写
    if(isupper('A')) cout<<"是大写";
    if(islower('a')) cout<<"是小写";
    if(isdigit(1)) cout<<"是数字";
    if(isspace(' ')) cout<<"是空格";
    return 0;
}

  七、:: 细节注意 ::

  1. 新建变量与变量之间赋值,不能同时进行。
  2.  ---- 错误示范! ----
    string str1=str2=""; 
     ---- 正确示范 ----
    string str2,str1;
    str1 = str2 = "";



借鉴博客、视频、网站:

1、集合操作<algorithm>

2、<cmath> / C++

3、<algorithm> / C++

4、牛客

5、pat官网



相关文章:

  • React Native v0.78 更新
  • 基于Asp.net的零食购物商城网站
  • Java多线程与高并发专题——ConcurrentHahMap 在 Java7 和 8 有何不同?
  • AIGC(生成式AI)试用 26 -- 跟着清华教程学习 - 个人理解
  • 微服务通信:用gRPC + Protobuf 构建高效API
  • java面试项目介绍,详细说明
  • 如何同步this.goodAllData里面的每一项给到row
  • 基于PyTorch的深度学习3——基于autograd的反向传播
  • 为AI聊天工具添加一个知识系统 之136 详细设计之77 通用编程语言 之7
  • MARL零样本协调之Fictitious Co-Play学习笔记
  • Python练习(握手问题,进制转换,日期问题,位运算,求和)
  • 数据流图(实例)
  • 【ArcGIS/GeoScene Server】修改密码
  • 颈椎X光数据集(cervical spine X-ray dataset)
  • MySQL 数据库连接池爆满问题排查与解决
  • 数据挖掘校招面经二
  • 爬虫面试:关于爬虫破解验证码的13个经典面试题
  • c++类继承的一些反思
  • C++ 测试案例
  • 第六节:基于Winform框架的串口助手小项目---收发数据《C#编程》
  • 网站建设所需材料/关键词排名方法
  • 百度竞价推广开户内容/搜索引擎优化常用方法
  • 北京网站制作济南/河北网站优化公司
  • 顺德网站建设怎么样/石家庄seo外包的公司
  • 互联网开网站怎么做/微信推广平台自己可以做
  • 河南seo和网络推广/seo优化教学视频