文章目录

1.申请数组

如果数组大小较大(大概10^6)则需要定义在main函数外,否则会使程序异常退出(因为函数内部申请的局部变量来自系统栈,即允许申请的空间较小;而函数外部申请的全局变量来自【静态存储区】,即允许申请的空间较大)。
另外:如果要对数组赋初值为0,可以用​​​int high[maxn]={0}​​,如果用vector容器则是定义后,默认容器内元素均为0

2.scanf的%c和%s

scanf的%c格式时可以读入空格和换行\n的;%d的输入则是以空白符(即空格、换行等)作为结束判断标志。
字符数组使用%s格式读入时的结束标志:空格、换行符。

#include <stdio.h>
int main(){
int a;
char c,str[10];
scanf("%d%c%s",&a,&c,str);
printf("a=%d,c=%c,str=%s",a,c,str);
system("pause");
}

输入的结果是:1 a bcd
输出的结果是:a=1,c= ,str=a
int型变量a遇到空格时停止读入(a不包含空格);而char型字符变量c(注意不是字符串变量)实际是一个空格——%c可以读入空格;str字符串变量为a(a后面即空格——结束)。

3.double

double型变量的输出格式为%d,而scanf输入的格式时%ld。
对于浮点型,不要使用float(因为精度只有6~7位),即只要是浮点型就使用double型最保险。

4.无穷大数

const int INF1=(1<<30)-1;
const int INF2=0x3fffffff
const int INF3=1e12;//很大的数,表示10^12

上面两种写法都是可以的;注意1<<30必须加括号(因算术运算符的优先级高于位运算符)。
如果是定义long long型的最大值则是long long inf=(1 long long <<63)-1;
注意:const用来定义常量,如const double pi=3.14;
另一种定义符号常量的方式是:【宏定义】#define pi 3.14

5.memset赋值

(1)添加头文件#include <string.h>
(2)用memset给数组赋值全部为0或-1(因为memset是按字节赋值,即组成int型的4个字节都会被赋成相同值——0的二进制补码为全0,-1的二进制补码为全1)
——memset(数组名,值,sizeof(数组名))
(3)若对数组赋值其他数字(如1)则使用fill函数。

6.字符数组2种初始化

(1)和普通数组一样逐个赋值:​​char str[15]={'g','m','s'}​​​;
(2)直接通过字符串初始化(只有初始化可以,其他地方不能这样直接赋值整个字符串):
​​​char str[15]="guomiansheng"​​​ 打印则用for循环逐个:​​printf("%c",str[i])​

7.用while接收输入

// 使⽤while接收输⼊的两种⽅式
while(scanf("%d", n) != EOF) {}
// 等价于下⾯这种:
//因为EOF⼀般为-1,所以~按位取反-1正好是0,就可以退出循环了
//所以也写成下⾯这种情况
while(~scanf("%d", &n)) {}

如果在自己的编译器运行后的命令行这样做会得不到输出结果(因为计算机一直在等你的输入结束,你需要在黑框中手动输入后,用<Ctrl+Z>组合键后按键来高速系统已经到达了EOF即到达了所谓的“文件末尾”——这样系统才会结束while),但是OJ却能AC,因为OJ会自己判断输入文件有没有已经读取完

8.说反话

实现的效果是【输入】Hello World Here I Come;【输出】Come I Here World Hello。
——相当于结合了第二条笔记和第七条笔记,用while循环接收输入,一直输入直到文件末尾:

#include<cstdio>
int main(){
int num=0;//单词的个数
char ans[90][90];
while(scanf("%s",ans[num]!=EOF)){//一直输入直到文件末尾
num++;//单词个数加1
}
for(int i=num-1;i>=0;i==){//倒着输出单词
printf("%s",ans[i]);
if(i>0) printf(" ");
}
system("pause");
}

9.sort排序

(1)sort默认是从小到大排序,可以使用cmp改变排序规则;
(2)注意排序cmp写法,如下面栗子:如果a和b身高不同则按从大到小的身高排序,如果a和b的身高相同则按名字降序排序。
(3)记忆方法:return的“大于”就是按从大到小排列。

struct node{
string name;
int height;
};
int cmp(struct node a,struct node b){
return a.height != b.height ?a.height>b.height:a.name<b.name;
}
sort(v.begin(),v,end(),cmp);

10.字符串hash(进制转换)

若要一个字符串S哈希映射为一个整数(唯一),26个大写字母对应到二十六进制中,即将二十六进制转为十进制,但若字符串包含小写字母则是将五十二进制转换为十进制(若字符串包含数字,就将进制数增大为62):

int hashFunc(char S[],int len){//hash函数,将字符串S转为整数
int id=0;
for(int i=0;i<len;i++){//如果len未知,可以用strlen(S)
if(S[i]>='A'&&S[i]<='Z'){
id=id*52+(S[i]-'A');
}else if(S[i]>='a'&&S[i]<='z'){
id=id*52+(S[i]-'a')+26;
}
}
return id;
}

11.判断素数

如果n没有接近int型变量的范围上界,可这以下这么写。这种写法会当n接近int型变量的范围上界时导致i*i溢出(n在10^9以内都是安全),解决方法是将i定义为long long型就不会溢出了。

bool isprime(int n){
if(n<=1) return false;
for(int i=2;i*i<=n;i++)
if(n%i==0) return false;
return true;
}

柳神版本:

bool isprim(int a){
if(a<=1) return false;
int Sqrt=sqrt((double)a);
for(int i=2;i<=Sqrt;i++){
if(a%i==0)
return false;
}
return true;
}

sqrt函数为一个浮点数开根号,要加<math.h>头文件。

12.vector数组

其实就是像一个二维数组,如​​vector<int> vi[100]​​​表示每个​​vi[i]​​​都是一个vector容器,如给出每门课上的学生,可以用vector数组​​vector<int> selectCourse[M]​​​的​​selectCourse[i]​​​保存每个学生i所选择的所有课程。
每次for循环即即可,把该学生所选择的课程编号加入该学生的选择(即vector)中。
——​​​selectCourse[id].push_back(course)​​。

13.auto遍历

#include<iostream>
#include<vector>

int main(){
std::vector<int> arr{11,22,33,44,55};
for (auto n : arr){
std::cout << n <<" ";
}
return 0;
}

14.申请内存空间

头结点head的数据域不放任何内容。
内存泄漏:申请内存空间后没有释放,导致在程序结束前始终占据该内存空间,而在一些较大的程序中容易导致内存消耗过快导致最后没有内存可以分配
每次需要使用新结点时临时分配相应大小的内存空间给新结点:

方法一:用C语言的malloc函数:

——使用<stdlib.h>头文件,
如​​​int* p=(int*)malloc(sizeof(int))​​用malloc函数向内存申请一块大小为sizeof(int)的空间,并返回指向该空间的指针(该指针的类型未确定,所以在malloc前面使用了int*,代表强制类型转化为int指针类型),最后将这个指针赋值给int型指针。

释放空间:​​free(p)​​——指针变量p本身是没有消失,只不过让p指向了空地址NULL,但是p原指向的内存是确实被释放了的

方法二:用C++的new运算符:

如​​int* p=new int;​​​即只需要“new+类型名”即可分配该类型的内存空间,并返回一个对应类型的指针;如果申请失败(一般指申请了较大的动态数组,如​​int* p=new int[10000000]​​​),​​new​​​则不会像malloc一样返回空指针,而是启动C++异常机制处理——发生异常,在无特殊处理情况下直接退出程序。
释放空间,

释放内存:​​delete(p)​​​。
PS:pat中内存大小一般够一道题用,所以不释放空间也没有啥影响,但是平时一定要养成即时释放空间的习惯。

15.静态链表

(1)静态链表不需要头结点;其结点定义如下:

struct Node{
typename data;//数据域
int next;//指针域
}node[size]

(2)在使用静态链表时,不要把结构体类型名和结构体变量名取成相同的名字(即Node和node)——一般情况是可以相同的,但是由于静态链表是由数组实现的,即可能对数组进行排序,如果两者相同则sort函数就会报编译出错。

16.构造函数

(1)只要参数和类型不完全相同,就可以定义任意多个构造函数,以适应不同的初始化场合。
(2)构造函数不需要写返回类型,且函数名与结构体名相同
(3)结构体内会生成一个默认的构造函数(但不可见,如​​​studentInfo(){}​​​),如下,所以才可以直接定义studentInfo类型的变量而不进行初始化(因为它没有让用户提供任何初始化参数)。
构造函数也可以直接化简成一行:

struct studentInfo{
int id;
char gender;
//默认生成的构造函数
studentInfo(int _id,char _gender): id(_id),gender(_gender){}
};
//这样就可以在需要时直接对结构体变量进行赋值
studentInfostu=studentInfo(10086,'M');

17.上机考试刷题模板

#include<iostream>//还有一堆头文件
using namespace std;

int main(){
#ifdef
#else
freopen("1.txt", "r", stdin);
#endif
/* your code */
return 0;
}

先在这个模板的同一级目录下建一个’1.txt’的文件,然后把输入全部放进去保存,然后就好了!之后你运行代码完全不用输入任何数据,模板会自行把文件中的数据读进来当做输入,不会有任何格式的差错,如果你在写’1.txt’的时候没错的话。
之后每换一道题就只需要修改1.txt的内容,如果你还是要在黑窗口里复制粘贴的话,可以再黑窗口右键,然后你就知道了。

18.多种容器混用

(1)为了建立书名、作者、关键词、出版社及出版年份与书籍编号的map映射关系,
可利用​​​map<string,set<int>>​​​,即​​map<string,set<int>> mpTitle,mpAuthor,mpKey,mpPub,mpYear​​​。
每次读入一本书的相关信息,就将该书的书名、作者、关键词信息的map中存入该书的书籍编号。

这里顺便复习下getchar、getline、scanf的一个栗子——读入书籍的关键词这行时,关键词可能是有多个,但是在像​​A1022​​​这题要求中,在查询过程中只是输入其中的某个关键词,所以为了后面的查询,需要在读入该本书的关键词时将该行关键词进行分别【分离】,实现方法:
用​​​cin​​​读入单个关键词,然后用​​getchar​​​接收该关键词后面的字符——如果是换行符,则说明关键词的输入结束;如果是空格,则继续读入。这样就实现关键词的每个词存入map型mpKey的键key对应的值,即set中,而在查询过程中,用迭代器for遍历即可,别忘了​​map.find(str)​​用法:查询map的键为str的映射的迭代器。

while(cin>>key){//每次读入单个关键词key
mpKey[key].insert(id);//把id加入到key对应的集合中
c=getchar();//接收关键词key之后的字符
if(c=='\n') break;//如果是换行,说明关键词输入结束
}

19.将字符串按字典序排序

<string>vec(n);
for(int i=0;i<n;i++){
cin>>vec[i];
}
sort(vec.begin(),vec.end());

20.将句子逆序

<string>ans;
string str;
while(cin>>str){
ans.push_back(str);
}
for(int i=ans.size()-1;i>=0;i--){
cout<<ans[i]<<" ";
}

21.sort从大到小排序

#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
using namespace placeholders;

class Cmp {
public:
bool operator()(int a, int b) {
return a > b;
}
};

bool cmp(int a, int b) {
return a > b;
}

int main() {
int a[10];
for (int i = 0; i < 10; i++) {
a[i] = (i + 5) * (i + 5) % 47;
}
for (int i : a) {
cout << i << ' ';
}
cout << endl;

sort(begin(a), end(a), cmp);
sort(rbegin(a), rend(a));
// 重载函数调用运算符
sort(begin(a), end(a), Cmp());
// 标准库定义函数对象
sort(begin(a), end(a), greater<>());
// lambda表达式
sort(begin(a), end(a), [](int a, int b){return a > b;});
// bind+lambda表达式
sort(begin(a), end(a), bind([](int a, int b) { return a < b; }, _2, _1));

for (int i : a) {
cout << i << ' ';
}
return 0;
}

22.