transform函数
C++中有两个函数可进行快速变换大小写,tolower()函数是把字符串都转化为小写字母;toupper()函数是把字符串都转化为大写字母。故上述代码中transform函数可写为:
transform(first.begin(),first.end(),second.begin(),::tolower);
这篇博客写的很详细:C++中的transform()函数_东北某985机械转CS工科男一枚的博客-CSDN博客_c++ transform函数
" "和' '的区别
" "视为字符串,且编译器在后面自动加上’\0’
''则视为单个字符,整型
输入输出字符
getchar函数,读取字母;
putchar函数,输出字母。
sort函数使用:升序 or 降序
sort一般都是升序排序
Sort函数的第三个参数可以用这样的语句告诉程序你所采用的排序原则
less<数据类型>()//从小到大排序
greater<数据类型>()//从大到小排序
若要使用降序排序两种方法
bool cmp(int x, int y){
return x > y;
}
int main(){
sort(a, a + n, cmp);
}
sort(a, a + n, greater<int>());
int, long long 等数据范围以及做题注意事项
int 范围在2e9左右,一般累计求和sum的时候就需要考虑long long
正常oj运算次数在1e8到1e7左右,超过后考虑优化
int最小 0x8fffffff(-7fffffff) 最大0x7fffffff,32位,十六进制表示8位
2的m次方简单表示 1<<m;
long long 上限2e20左右
最大值 / 最小值
分析:
当a >= b时,max(a, b) = (a + b + a - b) / 2 = a;
当a < b时,max(a, b) = (a + b + b - a) / 2 = b;
同理,最小值公式为
min(a ,b) = (a + b - abs(a - b)) / 2;
头文件
C++ 中 algorithm 头文件下有 max( )、min( )
特例:
有些题有小坑,使用max函数,比如max(a,0)时,若a是long long 类型,就会报错,需要将0改成0ll
加权平均数
加权平均数,是具有不同比重的数据(或平均数)的算术平均数。
比重也称为权重,数据的权重反映了该变量在总体中的相对重要性,每种变量的权重的确定与一定的理论经验或变量在总体中的比重有关。依据各个数据的重要性系数(即权重)进行相乘后再相加求和,就是加权和。加权和与所有权重之和的比等于加权算术平均数。加权算术平均数主要
用于原始资料已经分组,并得出次数分布的条件。
题目举例
读取两个浮点数 A 和 B 的值,对应于两个学生的成绩。
请你计算学生的平均分,其中 A 的成绩的权重为 3.5,B 的成绩的权重为 7.5。
成绩的取值范围在 0 到 10 之间,且均保留一位小数。
输入格式
输入占两行,每行包含一个浮点数,第一行表示 A,第二行表示 B。
输出格式
输出格式为 MEDIA = X
,其中 X 为平均分,结果保留五位小数。
数据范围
0≤A,B≤10.0
输入样例:
5.0
7.1
输出样例:
MEDIA = 6.43182
#include<iostream>
using namespace std;
int main(){
double a, b;
cin >> a >> b;
printf("MEDIA = %.5f", (a * 3.5 + b * 7.5) / 11);
return 0;
}
二进制左右移位
左移操作
二进制每左移一位就是*2,两位就是*2*2,三位就是*2*2*2.
1先转成二进制 在左移n位 然后补0
比如 1<<2 1的二进制为 0000 0001 左移2位 0000 0100.
n=1 即 1*2
n=2 既1*2*2
n=3 既1*2*2*2
就是进行二进制的翻倍。
1>>n就是1右移n位
n>>1就是n右移1位
1<<n就是1左移n位
n<<1就是n左移1位
int m=1<<n
右移操作(>>)
规则:
左边空出的位用0或者1填补。正数用0填补,负数用1填补。注:不同的环境填补方式可能不同;
低位右移溢出则舍弃该位。
右移一位相当于除以一个2
例如:20 的二进制为 0001 0100 ,那么10右移3为就是 0000 0010,结果就是2。
20>>3 ==2
逻辑运算符 【&& || ! 】
#include <bits/stdc++.h>
using namespace std;
int main(){
int i = 0, j = 0, k = 0;
++ i || ++ j && ++ k;
cout << i << endl;
cout << j << endl;
cout << k << endl;
return 0;
}
运行结果
1
0
0
程序中的短路问题
- || 从左向右开始计算:
当遇到为真的条件时停止计算,整个表达式为真
所有条件为假时表达式才为假
&&
从左向右开始计算:
当遇到为假的条件时停止计算,整个表达式为假
所有条件为真时表达式才为真逻辑表达式中,
&&
比||
具有更高的优先级
&&和||的短路运算,是指如果在进行前面的表达式的运算过程,通过判断已经明确的知道整个表达式的结果,那么就不会进行后面表达式的运算判断。例如:
表达式1 || 表达式2 || 表达式3...|| 表达式n,如果表达式1的运算结果为true,则整个表达式的结果为true,同时不会再对后面的表达式2、表达式3到表达式n进行运算判断。如果表达式1的运算结果为false,则根据表达式2的运算结果继续判断。
表达式1 && 表达式2 && 表达式3...&& 表达式n,如果表达式1的运算结果为false,则整个表达式的结果为false,同时不会再对后面的表达式2、表达式3到表达式n进行运算判断。如果表达式1的运算结果为true,则根据表达式2的运算结果继续判断。
在&&
和||
混合运算时,整个表达式被看作||
表达式(因为||
的优先级低于&&
,因此最后运算||
),编译器从左向右开始计算&&
表达式,当某个&&
表达式的值为真时,停止计算,整个表达式值为真。
- 程序中的逻辑表达式遵循短路规则
- 在
&&
与||
混合运算时:
整个表达式被看作||
表达式
从左向右先计算&&
表达式
最后计算||
表达式- 逻辑非
!
运算符只认得0:遇见0返回1,否则统统返回0
ceil函数
在 C 语言中 ceil 函数用于对浮点数 float 或者 double 或者 longdouble 向上取整,也是一个比较常用的函数 ,语法如下:
#include <math.h> //需要包含头文件
extern float ceilf(float); //参数为flot类型
extern double ceil(double); //参数为double类型
extern long double ceill(long double); //参数为long double类型
注意:ceil 函数的返回是 double 类型,并非 int 类型;
对数函数的使用
__lg(len) : 以 2 为底的对数
求最大公因数的简单函数
__gcd( , );
set的使用
set中常用的方法
begin() ,返回set容器第一个元素的迭代器
end() ,返回一个指向当前set末尾元素的下一位置的迭代器.
clear() ,删除set容器中的所有的元素
empty() ,判断set容器是否为空
max_size() ,返回set容器可能包含的元素最大个数
size() ,返回当前set容器中的元素个数
rbegin() ,返回的值和end()相同
rend() ,返回的值和begin()相同
1、set中的元素都是排好序的
2、set集合中没有重复的元素
和find一起使用时在set中找不到数值时的表达:
set<int> s;
if(s.find(b[j])==s.end())//b[j]不在set<int> s中
{
s.insert(b[j]);//执行操作
}
EOF的用法(while(scanf(“%d“,&n) != EOF)) 和
~取反的用法(while(~scanf(“%d“,&n)))
scanf的返回值就是“所输入的数据与格式字符串中匹配次数.”
对于scanf("%d",&x);
如果你输入一个数字,则匹配成功,返回1;
如果你输入一个字符或其他,则匹配失败,返回0;
如果你输入^Z(就是键盘的ctrl+z),则输入错误返回-1。
那么scanf("%d%d",&x,&y) 则同理,不同输出会返回 2 1 0 -1。
或许有小伙伴会问,这和EOF有啥关系呢?
EOF是End Of File(文件结束)的缩写,在c语言库中有这样一行代码:
#define EOF -1
EOF被定义为-1这个常量。
下面回到while(scanf("%d%d",&x,&y)!=EOF)
当你加上这个时,只要你不输入^Z scanf的返回值就>=0 不等于-1 条件为真,一直循环下去,
只有你输入^Z,条件为假,终止循环。
这就是我们所说的多组输入。
原文链接:EOF的用法(while(scanf(“%d“,&n) != EOF))和~取反的用法(while(~scanf(“%d“,&n)))_diviner_s的博客-CSDN博客
我们讲了怎么多组输入数据,接下来就是怎么结束输入了。我们重看之前开篇写的后两种情况,
情况二:没有说固定的数据量,只给出以某一特定标识符作为结束标志,结束输入数据。常见是以输入0作为结束标志。
情况三:与情况二大致一样,但是结束没有固定标识符,以手动结束输入循环。
我们分析情况二,以某一特定结束符作为终止循环的条件,通常是将0作为终止标志。
解决方法:while( scanf("%d",&n) != EOF, n ){ }我们来看括号中的n代表的是若我们在前一句输入的是0,即此时n = 0即表达式为否需要结束循环,即实现了结束多次输入数据。
若是将-1作为终止标志,那我们就可以这样写while( scanf("%d",&n) != EOF, n != -1) { }即当输入-1时,n此时==-1,则表达式n != -1为 -1,结束循环。
分析情况三,无固定结束标识符,手动结束多组输入。
解决方法:在终端(黑框)中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾”,因此需要用<Ctrl + z>组合键然后按 Enter 键的方式来告诉系统已经到了EOF,这样系统才会结束while.
~取反的用法
~是按位取反的意思。
scanf的返回值是输入值的个数
如果没有输入值就是返回-1,将-1按位取反结果是0
while(~scanf("%d", &n))就是当没有输入的时候退出循环,这也符合上面的结束循环条件。
关于%I64d和%lld的问题
两种都是C语言中格式化输出64位整型的正确做法。
区别在于编译器不同。
gcc(mingw32),g++(mingw32)只支持%I64d的输出方式。
gcc(linux i386),g++(linux i386)只支持%lld的输出方式。
另外,mac上的gcc/g++不支持%I64d的方式。