字符串篇
1、strlen是O(n)的复杂度,所以类似for(int i=0;i<strlen(s);i++){}
之类的语句,时间复杂度是$O(n^2)$。但是,string对象的size函数的复杂度是O(1),要注意区别。
2、gets函数已经被noip禁用,可用fgets函数替代,注意:fgets会把最后的回车包含到目标数组。
3、string对象可以进行加法运算,只+
两边有string对象,就会全部转为string再连接。注意:如果+
两边没有string对象,都是char字符串,那么就会报错,比如:string s="hello"+"world";
,正确写法是string s1="hello"; string s2=s1+"world";
,这样写也是错的:string s2="dahua" + "hao" + s1;
因为先计算第一个+
号,但这时两边全是char字符串。
4、注意strcmp函数是根据返回值来进行判断,千万不要忘了要对strcmp的返回值进行判断,分==0,>0,<0三种情况。一个常见错误是if(strcmp(s1,s2)){}
这时不对的,正确写法if(strcmp(s1,s2)==0){}
5、为什么for (auto c : s1) s2 = s2 + c + ' ';
就可以,但是写成for (auto c : s1) s2 += c + ' ';
就不行呢?
答:后面那种写法计算的是两个字符对应的ascii的和,而不是把两个字符连接起来。
6、处理fgets的回车符号:
fgets(a,sizeof(a),stdin);
int la=strlen(a);
if(a[la-1]=='\n'){
a[la-1]='\0';
la--;
}
很罗嗦是不是?但我觉得没法再减了,有办法的告诉我一声,a字符串的长度尾la,后面可能用的,故要维护。
7、用scanf读入字符不能过滤空白字符,也就是op会把空格和回车都读进来,如果想scanf过滤空白,可以把读入字符改为读入字符串。
char c,op[10];
scanf("%d%c",&a,&c); //如果输入:3 H 会导致a=3,c=' '。
scanf("%d%s",&a,op): //改为字符串就不存在这个问题了,结果为:a=3,op=H
位运算技巧
1、判断两个整数是否相等,可以用异或。a ^ b
。还可以利用这个特点。缩短结构体排序。如:
struct node{
int a,b;
};
bool cmp(node x,node y){
return x.a^y.a?x.b>y.b:x.a>y.a;
}
2、由于-1
的二进制是32个1,利用这个可以做很多事:,如关系表达式i>=0
可以用位运算~i
来代替。输入EOF后停止循环,可以写为while(~scanf("%d",&a){}
,都是因为-1
求反得0的原因才可以成立。
3、判断int a中从右往左第一个1,利用位与运算:a&(-a)
,参考lowbit函数。