方法技巧,注意事项这类小知识点吧

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类

stringprintf输出方式:printf("%s",s.c_str());

使用getline()读取一整行getline(cin,s)

stringemptysize操作:

//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中的每一个元素,并将其赋值给variablecollection是需要遍历的集合,可以是数组、容器、字符串等
这不就是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::cinscanf()std::coutprintf()

但可以同时使用std::cinprintf()std::coutscanf()


STL类

#include <algorithm>

reverse翻转
翻转一个vectorreverse(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()来输入

posted @ 2023-08-27 23:35  -37-  阅读(11)  评论(0编辑  收藏  举报