PAT编程笔记
知识点总结
-
定义之后一定要初始化
-
尽量都使用
vector,速度vector>set>map -
两个关键字排序简洁写法
return a.height != b.height ? a.height > b.height : a.name < b.name; -
使用
10*1.0的方式去输出小数,除非必要。否则可以不用定义double -
一定要考虑到为
0或1这些边界条件 -
传参数尽量使用引用来加快速度
-
将字母编号时。字母和数字都进行映射,这样方便根据字母取数字,根据数字取字母
-
string name(ch)将字符数组ch转化为string字符串 -
printf("%%");打印一个% -
string.c_str(),将string类型转化为char*类型,以便printf()输出。 -
auto - 声明变量时根据初始化表达式自动推断该变量的类型,少了初始化就会出错
-
getline (cin,name)- 以'\n'结束 -
int-10^9long long-10^18long long类型常量需要在后面加上LLlong long bignum=1234456789097LL -
碰到浮点都用
double -
宏定义后面不需要加分号
-
使用数学函数加
math.h -
\0的ASCII码为零,即NULL -
运行错误可能是因为数组开小了
-
如果数组有10^6需要定义在主函数外面
-
用
getchar和putchar来输入输出单个字符,可以读取回车 -
void change(int a[],int b[][5])数组作为参数时,数组的第一维不需要填写长度 -
A ? B : C;如果A为真,那么执行并返回B的结果;反之执行并返回C的结果 -
除了
%c,scanf对其他格式符的输入是以空白格(空格,换行等)为结束判断标志%c是可以读入空格跟换行的 -
puts和printf通过\0来作为字符串结束的输出的,所以输出时要保证字符串结尾有\0,否则printf会因无法识别字符串而输出乱码 -
vector prime(500000,1);vector初始化 -
处理大数运算时,对每一个字符的运算可以先减‘0’使其变成数字去运算,运算结果出来后再加
'\0'使其变回字符串 -
堆是一个完全二叉树,要用数组存储
-
尽量使用
fill(),少使用meset()C++使用fill初始化二维数组
fill(dis[0], dis[0]+maxn*maxn, INF); -
无穷大:
const int INF = 100000000; -
typedef给数据类型起别名typedef long long LL; -
getline,gets[参考]
getline(cin,query);cin.getline(S1,10010);S1为数组,10010是数组大小 -
scanf与cin都以空白格为结束标志,不会读取他们,所以它们会遗留在读取缓存中。但是只有在scanf与gets使用或cin使用后紧接着又使用getline时,就需要吸收掉它们后面的字符tmp=getchar()[参考] -
string.h头文件strcmp()比较两个字符串- 字符串1<字符串2 返回负数
- 字符串1=字符串2 返回0
- 字符串1>字符串2 返回正数
strcpy(str1,str2)把字符串2复制给1,包括\0strcat(str1,str2)把字符串2接到1后面截取子串
s.substr(pos, n)截取s中从pos开始(包括0)的n个字符的子串,并返回s.substr(pos)截取s中从从pos开始(包括0)到末尾的所有字符的子串,并返回
int与string转换
voidtestTypeConvert()
{
//int --> string
int i = 5;
string s = to_string(i);
cout << s << endl;
//double --> string
doubled = 3.14;
cout << to_string(d) << endl;
//long --> string
longl = 123234567;
cout << to_string(l) << endl;
//char --> string
charc = 'a';
cout << to_string(c) << endl; //自动转换成int类型的参数
//char --> string
string cStr; cStr += c;
cout << cStr << endl;
s = "123.257";
//string --> int;
cout << stoi(s) << endl;
//string --> float
cout << stof(s) << endl;
//string --> doubel
cout << stod(s) << endl;
//string --> char*
char *p=(char*)s.c_str();
}
字母转换大小写
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string str="how are you";
transform(str.begin(),str.end(),str.begin(),::toupper); //转大写
transform(str.begin(), str.end(), str.begin(), ::tolower); //转小写
cout << str << endl;
return 0;
}
- 随机函数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int main()
{
int left=1000,right=6000;
srand((unsigned)time(NULL)); //生成随机种子
//可用于生成快排的主元
int rd=(int)(round(1.0*rand()/RAND_MAX*(right-left)+left)); //随机生成left-righth中的一个值
printf("%d\n",rd);
return 0;
}
结构体定义与初始化
//定义
struct person{
int ID;
char name[10];
};
//定义并且定义变量
struct person{
int ID;
char name[10];
}myj={0,"myj"},students[2]={10,"BISEN",11,"zhiming"}; //定义一个变量或者数组
//定义并且初始化
struct person{
int ID;
char name[10];
};
struct person{
int ID;
char name[10];
person(int _ID,char _name[10]) //定义初始化函数
{
ID=_ID;
strcpy(name,_name);
}
}*p; //定义一个结构体指针,用p->ID访问ID变量
person student=person(10,"LILI"); //定义并初始化
输入输出函数
- scanf
| int | %d |
|---|---|
| long long | %lld |
| float | %f |
| double | %lf |
| char | %c |
- printf
| int | %d |
|---|---|
| long long | %lld |
| float | %f |
| double | %f |
| char | %c |
- 输出格式
| %md | 使不足m位的int变量以m位进行右端对齐,高位用空格补齐。如果超过m位择保持原样 |
|---|---|
| %0md | 不足m位时在左边补零 |
常用数学函数
| fabs(double x) | 取绝对值 |
|---|---|
| floor(double x) ceil(double x) | 向下取整 向上取整 |
| pow(double x) | 求幂 |
| sqrt(double x) | |
| sin(double x) cos(double x) tan(double x) | |
| round(double x) | 四舍五入 |
C++ STl总结
vector
只有vector和string才允许vi.begin()+3这种迭代去加上整数的写法
vector常见用途
- 存储数据
- 使用在元素不确定的场合
- 保存部分输出,最后输出在同一行输出
- 用邻接表存储图
vector常用函数
push_back()- 在vector后面加上一个元素pop_back()- 在vector后面删除一个元素size()clear()- 清除所有元素inster(it,-1)-vi.insert(vi.begin()+2,-1)在任意迭代器处插入元素,复杂度O(N)erase()erase(it)- 删除单个元素,删除迭代器it处的元素erase(first,last)删除[first,last)区间内所有元素
#include <iostream>
#include <vector> //要加头文件
using namespace std;
int main()
{
vector<int> name; //可下标访问:name[3]
//定义vector数组,一维长度n被固定,二维才是可变的
vector<vector<int> > Arry[100]; //二维vector >> 之间要加空格
for(int i=0;i<5;i++)
name.push_back(i); //添加元素
vector<int>::iterator it=name.begin(); //vector迭代器
for(int i=0;i<5;i++)
printf("%d\n",*(it+i)); //通过迭代器访问
return 0;
}
set
内部自动有序且不含重复元素
set使用方法详细常用[参考]
set集合的交并补[参考2]
set常见用途
自动去重并按升序排列。要处理不唯一的情况适用multiset
set常用函数
insert(x)- 复杂度O(logN)find(value)- 返回set中对应值为value的迭代器,找不到就返回vi.end()复杂度O(logN)erase()erase(it)erase(value)- 根据迭代器和值去删除。vi.erase(vi.find(100))erase(first,last)删除[first,last)区间内所有元素
size()clear()
#include <iostream>
#include <set> //要加头文件
int main()
{
//定义
set<int> name;
return 0;
}
string
substr(pos,len)- 返回从pos号位开始,长度为len的字串find()str1.find(str2)-str2是str1字串返回第一次出现的位置,否则返回-1str1.find(str2,pos)- 从str1的pos号位开始匹配str2,返回值与👆相同 复杂度O(nm)
replace()-str1.replace(pos,len,str2)把str1从pos号位开始,长度为len的字串替换为str2erase()erase(it)erase(first,last)删除[first,last)区间内所有元素
length()size()clear()
#include <iostream>
#include <string> //要加头文件
using namespace std;
int main()
{
//string定义
string str="abc";
//整个的输入输出只能通过cin cout
cin>>str;
cout<<str<<endl;
//使用printf打印string。通过下标访问
for(int i=0;i<str.length();i++)
{
printf("%c",str[i]);
}
//迭代器访问
for(string::iterator it=str.begin();it!=str.end();it++)
{
printf("%c\n",*it);
}
//string支持两个字符串直接x相加
string str1="12";
string str2="34";
str=str1+str2;
//string可以直接进行比较
int p=str1>str2;
cout<<p<<endl;
return 0;
}
map
- 注意事项:在map中,由key查找value时,首先要判断map中是否包含key。[参考]
- map中的元素是自动按Key升序排序,所以不能对map用sort函数
- unordered_map速度更快。头函数
#include<unordered_map>
map常见用途:
- 需要建立字符串与整数之间映射的题目
- 判断大整数或者其他数据类型是否存在的题目,可把
map当bool数组使用 - 字符串映射到字符串
map可以代替hash的使用
map可以将任何基本类型映射到任何基本类型
会自动以键从小到大自动排序
find(key)- 返回键为key的映射的迭代器,不存在就返回end函数返回的迭代器 复杂度O(logN)erase()mp.erase(it)mp.erase(key)- 复杂度O(logN)erase(first,last)删除[first,last)区间内所有元素
size()clear()
#include <iostream>
#include <map> //要加头文件
#include <set>
using namespace std;
int main()
{
//定义 map<typename1,typename2> mp;
map<string,int> mp; //字符串到整形发的映射,不能使用char
map<set<int>,string> mp2;
map<char,int> mp3;
//赋值,
mp3['c']=10; //键只能有一个,当赋值时内部存在则修改,不存在就新建
mp['m']=20;
for(map<char,int>::iterator it=mp3.begin();it!=mp3.end();i++)
{
printf("%c %d\n",it->first,it->second);
}
//map与set组合使用,这样一个键可以对应多个值
map<string,set<int> > m;
m["book"].insert(123);
set<int>::iterator it=m["book"].begin();
printf("%d\n",*it);
//判断map中key值是否存在。如果键不存在访问会返回0
if (mymap.find(key) == mymap.end())
cout << "没有这个key" << endl;
if (mymap.count(key) == 0)
cout << "no this key" << endl;
return 0;
}
queue
push()pop()front()back()empty()size()
front() 和 pop()使用前要使用empty()判断队列是否为空
priority_queue
push()pop()top()empty()size()
- 使用
top()必须用empty()判断是否为空- 默认是最大堆
元素优先级设置
#include <iostream>
#include <queue> //要加头文件
using namespace std;
int main()
{
priority_queue<int> q;
//是double第二个参数就要变成vertor<double>
//less<int> 表示数字大的优先级越大 greater<int> 数字小的优先级大
priority_queue<int,vertor<int>,less<int> > q;
return 0;
}
结构体优先级设置
#include <iostream>
#include <queue> //要加头文件
#include <string>
using namespace std;
struct fruit{
string name;
int price;
friend bool operator < (fruit f1,fruit f2) //只需要重载小于号就行了
{
return f1.price>f2.price; //与排序的比较函数写法相反
}
}f1,f2;
int main()
{
priority_queue<fruit> q;
f1.name="桃子";
f1.price=3;
f2.name="梨子";
f2.price=1;
q.push(f1);
q.push(f2);
cout<<q.top().name<<" "<<q.top().price<<endl;
return 0;
}
stack
push()pop()top()empty()size()
pop()和top()之前需要使用empty()去判断是否为空
#include <iostream>
#include <stack> //要加头文件
using namespace std;
int main()
{
//定义
stack<int> s;
return 0;
}
pair
有两个元素的结构体
头文件:#include <map>
pair可以直接使用== <去比较,规则是先first再second比较
pair用途:
- 替代二元的结构体
- 作为
map的键值进行插入
创建:
-
pair<string, string>(first, second) -
make_pair(5,"hah")
algorithm
-
max(x,y)min(x,y)max(x,mac(y,z)) -
abs(x)- x必须是整数 -
swap() -
reverse(it,it2) -
sort()- 可对vector,string,deque使用第三个参数可不写,
默认升序比较函数:如果第一个参数排在第二个参数前面,返回
true,否则返回falsea<b就是排序规则,满足就返回true,不交换。反之亦然a==b是尽管返回false但是它不会位置调换sort函数中的陷阱:永远让比较函数对相同元素返回false。return a<=b //错误写法
bool compare(int a,int b)
{
return a<b; //升序排列,如果改为return a>b,则为降序
}
next_permutation()- 给出一个序列在全排列中下一个序列
#include <iostream>
#include <algorithm> //要加头文件
using namespace std;
int main()
{
int a[10]={1,2,3};
do{
printf("%d%d%d\\n",a[0],a[1],a[2]);
}while(next_permutation(a,a+3));
return 0;
}
fill()- 把数组区间赋值为某个值
#include <iostream>
#include <algorithm> //要加头文件
using namespace std;
int main()
{
int a[10]={1,2,3,4,5};
fill(a,a+5,1);
return 0;
}
-
lower_bound()upper_bound()在有序容器中lower_bound(first,last,val)- 寻找[first,last)区间内第一个值大于等于val的元素位置。是数组返回指针,容器就返回迭代器upper_bound(first,last,val)- 寻找[first,last)区间内第一个值大于val的元素位置。是数组返回指针,容器就返回迭代器

浙公网安备 33010602011771号