方法技巧,注意事项这类小知识点吧
cin
可以读取连续元素的单个元素,类似getchar()
使用printf
时最好添加头文件 #include <cstdio>
%08.3f
, 表示最小宽度为8,保留3位小数,当宽度不足时在前面补上(对整型补0时不能打点号)
fgets
不会删除行末的回车字符
strcmp(a, b)
比较两个字符串的大小,a < b返回-1,a == b返回0,a > b返回1。比较方式是字典序
下述for循环每次均会执行strlen(a)
,运行效率较低,最好将strlen(a)
用一个变量存下来
for (int i = 0; i < strlen(a); i ++ )
string s4(10, 'c'); // s4的内容是 "cccccccccc"
string类
string
的printf
输出方式:printf("%s",s.c_str());
使用getline()
读取一整行getline(cin,s)
string
的empty
和size
操作:
//empty()
/******************************************************
格式:bool empty ( mixed var )
功能:检查一个变量是否为空
返回值:
若变量不存在则返回 TRUE
若变量存在且其值为""、0、"0"、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回 TURE
若变量存在且值不为""、0、"0"、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回 FALSE
******************************************************/
string s1, s2 = "abc";
s1.empty() == 1;
s2.empty() == 0;
//size()
/******************************************************
size()函数除了跟length()函数一样可以获取字符串长度之外,还可以获取vector类型的长度
******************************************************/
s2.size() == 3;
size() - 1的坑:
/******************************************************
size是无符号整数,若size() == 0时再减1会导致溢出
解决办法:
1. int a = arr.size() - 1; // 赋值给有符号整数
2. 如果是做大小判断的话
if(index + 1 < arr.size()){}把 - 1 移到另一端即可
******************************************************/
string的比较
支持 >, <, >=, <=, ==, !=等所有比较操作,按字典序进行比较
两个string对象相加:
string s1 = "hello,",s2 = "world";
string s3 = s1 + s2; // s3的内容是 hello, world
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s4 = s1 + ", "; // 正确:把一个string对象和有一个字面值相加
string s5 = "hello" + ", "; // 错误:两个运算对象都不是string
string s6 = s1 + ", " + "world"; // 正确,每个加法运算都有一个运算符是string
string s7 = "hello" + ", " + s2; // 错误:不能把字面值直接相加,运算是从左到右进行的
处理string对象中的字符
string对象可以当成字符数组来处理:
string s = "hello world";
for (int i = 0; i < s.size(); i ++ )
cout << s[i] << endl;
C++11引入的for-each循环(也称为范围for循环)
for (variable : collection) {
statement(s);
}
其中,variable
是迭代变量,用于迭代遍历collection
中的每一个元素,并将其赋值给variable
;collection
是需要遍历的集合,可以是数组、容器、字符串等
这不就是python的for嘛
多维数组中,除了第一维之外,其余维度的大小必须指定a[][10]
结构体和类的作用是一样的。不同点在于类默认是private
,结构体默认是public
结构体和类都可以使用构造函数:
class none {
private:
int a;
int b;
public:
None(int _a, int _b) {
a = _a;
b = _b;
}
None(int _a, int _b) : a(_a), b(_b) {} //更快
}
转二进制
int ans = 0;
int n = 3;
for (int i = 9; i >= 0; i--) {
ans = ans * 10 + (n >> i & 1);
// cout << (n >> i & 1);
}
cout << ans;
从0开始的是下标,编号,而长度,数量是从1开始
关闭同步流提高输入输出效率
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
副作用:
不能同时使用std::cin
和scanf()
,std::cout
和printf()
但可以同时使用std::cin
和printf()
,std::cout
和scanf()
STL类
#include <algorithm>
reverse
翻转
翻转一个vector
:reverse(a.begin(), a.end())
翻转一个数组:reverse(a, a + n + 1)
结尾位置是末尾元素的下一个位置,记住左边取得到,右边取不到就行
unque()
去重
返回去重之后的迭代器(或指针),仍然为前闭后开,即这个迭代器是去重之后末尾元素的下一个位置。利用迭代器(或指针)的减法,可计算去重后的元素个数
vector
去重:
int m = unique(a.begin(), a.end()) - a.begin()
数组去重:
int m = unique(a, a + n + 1) - (a)
a.erase(unique(a.begin(), a.end()) , (a.end()));
random_shuffle()
随机打乱,用法与reverse相同
sort
排序
sort(a, a + n, cmp)
对两个迭代器(或指针)指定的部分进行快速排序。可以在第三个参数传入定义大小比较的函数,或重载“小于号”运算符
默认是从小到大排,可以使用greater<int>()
从大到小排
bool cmp(int a, int b) { //a是否应该排在b前面
//a排在b前面的条件
}
排序结构体:
struct Rec {
int x, y;
}a[5];
for (int i = 0; i < 5; i++) {
a[i].x = -i;
a[i].y = i;
}
bool cmp(Rec a, Rec b) {
return a.x < b.x;
}
//重载小于号
struct Rec {
int x, y;
bool operator< (const Rec &t) const {
return x < y;
}
};
lower_bound / upper_bound
二分
lower_bound
的第三个参数传入一个元素x,在两个迭代器(指针)指定的范围上执行二分查找,返回指向第一个大于等于x的元素的位置的迭代器(指针)
upper_bound
的用法和lower_bound
大致相同,唯一的区别是查找第一个大于x的元素
前提是两个迭代器(指针)指定的范围应该是排序好的
二分数组:
int *p = lower_bound(a, a + n, x)
二分vector
int *p = lower_bound(a.begin(), a.end(), x)
next_permutation
返回当前按字典序排列的下一种排列
无穷大
在算法竞赛中,我们常常需要用到设置一个常量用来代表“无穷大”。
比如对于int类型的数,有的人会采用INT_MAX
,即0x7fffffff
作为无穷大。但是以INT_MAX
为无穷大常常面临一个问题,即加一个其他的数会溢出。
而这种情况在动态规划,或者其他一些递推的算法中常常出现,很有可能导致算法出问题。
所以在算法竞赛中,我们常采用0x3f3f3f3f
来作为无穷大。0x3f3f3f3f
主要有如下好处:
0x3f3f3f3f
的十进制为1061109567
,和INT_MAX
一个数量级,即\(10^9\)数量级,而一般场合下的数据都是小于\(10^9\)的。
0x3f3f3f3f * 2 = 2122219134,无穷大相加依然不会溢出。
可以使用memset(array, 0x3f, sizeof(array))
来为数组设初值为0x3f3f3f3f
,因为memset
是按字节来设置的,所以这个数的每个字节都是0x3f
。
输入达到\(10^6\)左右需要使用scanf()
来输入