不定期更新
1.cin\cout太慢导致超时
找了很久,发现如果因为输入输出太慢导致超时,最好两个命令一起用。
ios::sync_with_stdio(false); cin.tie(0); //0表示NULL
这里额外说一下原理。我们一般情况下可以混用cin和scanf是因为cin与scanf保持了流同步。
C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起。
而也因此,cin变得缓慢,第一行代码便解除了流同步,从而提高cin效率。但是,这样做以后,
因为流不同步了,不能再混用c++和c的输入输出语句了。这个函数是一个“是否兼容stdio”的开关。
在默认的情况下,cin绑定的是cout,每次执行 << 流操作符的时候都要调用flush,这样会增加IO负担。
第二行的代码用来解除cin与cout的绑定,进一步加快执行效率。
即便如此,cin效率应该还是不及scanf,差不太多但是还是慢一点。(这句话是个人感觉)
2.变量定义位置的问题
开始acm道路之后,我习惯了把很多变量放到全局变量,省去函数之间引用传递的麻烦,
需要初始化的时候用memset。这个做法方便但其实有不安全的地方,那便是递归函数。
因为在递归函数中,某个变量在某次递归中都有一个值,可是如果将它声明为全局变量,
那该变量就不随着递归函数而改变。举个常见的例子,在dfs中for循环的回退,
如果意外(新人可能会这样做)将变量声明在for之外,就有可能有问题。
所以可能同样的代码,函数内使用局部变量的代码A了,而全局变量的WA了。
这个案例告诉我们,有时候wa了不是算法问题,只是因为一个变量的位置。
3.声明优先队列的时候
priority_queue默认为大顶堆,若要声明为小顶堆,需要
priority_queue<int,vector<int>,greater<int> > ipq;
此时“greater<int>”与 “>”中间要有一个空格,否则编译器会将两个'>'理解为流操作符。
额外说一句,如果不是int类型而是自定义类型,需要重载小于符号。sort()函数重载也是重载小于号。
4.在结构体、类中需要储存字符串的时候,可能导致的内存溢出错误(RE)
我们知道,可以用 string=char[]来初始化字符串。于是有次做字典树,用节点储存一个字符串,我在节点中声明了
个string变量,在insert的时候先new node(),然后直接让string=char[]导致RE。这是因为new的时候不知道
string占用的空间大小所以没分配(推断,应该是),解决方法,不要在node结构体/类中声明string,
而声明char* val; 在需要赋值的时候,使用以下代码来将字符串储存到节点中。
p->val = (char*)malloc((strlen(v)+1)*sizeof(char));//p是指向node的指针,v是待储存的字符串 strcpy(p->val,v);//将要存的字符串v存入p所指的结构体/类中的char*指针val所指的地址。
5.不要申请动态数组,直接全局变量,然后用memset重置就好了。memset因为底层的cache优化所以特别快
在比赛中,遇到动态数组问题一般不用申请动态数组。
比如用深、广搜的时候储存邻接矩阵,开个全局变量的大数组,然后每次都利用memset清0。
比如用深、广搜的时候储存邻接矩阵,开个全局变量的大数组,然后每次都利用memset清0。
用法是memset(数组名称,0/-1,sizeof(数组))
第二个参数填0代表将数组清0(填-1则将数组全部变成-1),
第二个参数填0代表将数组清0(填-1则将数组全部变成-1),
需要注意的是,填1等其他值不会将数组以1填充。
如果你想要将一个数组全部填成某个特定的数,请用fill函数
6.大量增删时应用list而非vector
7.c++读取一整行的方法汇总
string s;
getline(cin,s);
cout<<s<<endl;
char s[100];
scanf("%[^\n]%*c",s);
printf("%s\n",s);
char s[100];
gets(s);
printf("%s\n",s);
char s[100];
cin.get(s,100);
printf("%s\n",s)
char s[100];
cin.getline(s,100);
printf("%s\n",s);
getline(cin, line)
stringstream ss(line);
while(ss >> a){
cout << a<< endl;
}
8.使用系统函数进制转换
char *s; s=new char; int v=0x7fffffff; char *b; b=itoa(v, s, 16); printf("%s",b);这段代码输出的是整数最大值的16进制,所以输出7fffffff
9.灵活使用auto变量
c++新的auto是类型推断,以前的auto是自动变量。现在,可以用auto来写代码了! 不需要再写什么iterator了!
map<string,int> m; m["hello"]=1; m["world"]=2; for(auto i=m.begin();i!=m.end();i++){ cout<<i->first<<i->second<<endl; }