算法笔记(第二章)

2.1.2
遇到浮点型的数据,都应该用double储存,不要使用float
字符常量(必须是单个字符)必须使用单引号标注
字符串用双引号标记
2.1.3
强制类型转换
(新类型名)变量名
2.1.4符号常量和const常量
用一个标识符替换常量,又称宏定义或者宏替换

#define 标识符 常量
const 数据类型 变量名=常量

推荐使用const
//除此之外,define还可以定义任何语句(尽量不要用)

#define 标识符 任何语句和片段

2.1.5运算符
(1)算数运算符
对于除法运算符,当除数与被除数都是整数时是不会出现浮点数的
自增运算符,i++,是先使用i再加1,++i,是先加1再使用
(2)关系运算符
(3)逻辑运算符
(4)条件运算符
三目运算符:A?B:C如果A为真,执行并返回B结果。如果A为假,执行并返回C结果。
(5)位运算符:位运算符没有算数运算符高
六种位运算符:
1. List item a<< x 左移 整数a按二进制向左移x位
2. List item a>>x 右移 整数a按二进制向右移x位
3. a&b 位与 整数a与b按二进制对齐,按位进行与计算(除了11得1,其他均为0)
4. a!b 位或 整数a与b按二进制对齐,按位进行与计算(除了00得0,其他均为1)
5. a^b 异位或 整数a与b按二进制对齐,按位进行与计算(相同为0,不同为1)
6. ~a 位取反 整数a的二进制的每一位进行0变1,1变0

2.2顺序结构
2.2.1赋值表达式:
赋值运算符可以通过其他运算符放在前面来实现赋值操作的简化 ,如:a+=2
2.2.2 scanf与printf 输出与输入
scanf(“格式控制”,变量地址);
scanf除了%c,对其他格式符的输入以空白符(即空白、Tab)为结束标志的
double类型在输出格式变成了%f,在scanf是%lf
(1)%md :可以使不足m位的int型以m位进行右对齐输出
(2)%0md:与%md不同的是,不足补0
(3)%.mf:让浮点数保留m位小数输出
2.2.3使用putchar与getchar输入\输出字符
getchar用来输入单个字符,putchar用来输出单个字符
getchar可以识别换行符
2.2.4注释
2.2.5 typedef:给复杂的变量类型起一个别名
如:

typedef long long LL;

2.2.6 常用math函数
(1)fabs(double x): double类型取绝对值
(2)floor(double x)和ceil(double x):向下取整和向上取整
(3)pow(double r,double p):函数用于返回r的p次方
(4)sqrt(double x) :用于返回x的算数平方根
(5)log(double x) :返回以自然数为底的对数
(6) sin(double x)、cos(double x)、tan(double x):正弦、余弦、正切值
(7)asin(double x)、acos(double x)、atan(double x):反正弦、余弦、正切值
(8)round(double x):将double进行四舍五入,返回类型也是double
2.3选择结构
2.3.1 if语句
**一个小技巧:**表达式是“!=0”或者“==0”,可将其省略
例如:

if(m){
}

2.3.2if嵌套语句
2.3.3 switch语句 (分支少,很少使用)
2.4循环结构
2.4.1 while语句:
有一个与if一样的小技巧:
如果表达式是“!=0”,可将其省略
如果表达式是“==0”,将其省略,并在表达式前面加“!”
2.4.2 do,while循环
先循环一次,在判断条件
2.4.3 for循环
for(循环变量初始化;循环条件;循环变量改变){
}
2.4.4 break与continue语句
break,退出循环
continue,即该语句以下不循环,执行i++后进入下一层循环
2.5 数组
2.5.1 一维数组
数组:把相同的数据类型的变量组合在一起而产生的数据集合。
递推:根据一些条件,可以不断让后一位的结果由前一位或前若干位来计算得来。递推分为顺推和逆推。
2.5.2 冒泡排序
排序是指将无序序列按照某一规则进行有序排列。
冒泡排序得本质在于交换,即每次通过交换的方式把当前剩余的元素的最大值移动到一端,而当剩余元素减少到0时,排序结束。
2.5.3 二维数组
二维数组初始化:a[5][6]={{1,2},{},{3,4,5}};
如果数组较大(大约10的6次方),需要将其定义在主函数外面,否则使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许的申请空间较小。而函数外部申请的全局变量来自静态存储区,允许存储的空间较大。
2.5.4 memset–对赋值的每一位元素赋相同的值
一般来说,给每个元素赋值有两种方法:memset函数和fill函数,其中fill函数在algorithm头文件中,memset在cstring头文件中。
memset的格式:memset(数组名,值,sizeof(数组名));
只建议初学者使用memset赋0或-1,其他请使用fill函数(memset比fill快)
2.5.5 字符数组
(1)字符数组的初始化:char str[15]={‘1’,‘2’,’’,’'5};
(2)字符数组的输入输出:字符数组就是char数组,当维度是一维时可以当作“字符串”。二维可当作“字符串数组”。字符数组输入除了有scanf外,还有getchar和gets;输出除了有printf,还有putchar或者puts.
scanf输入、printf输出,%c用来输入单个字符,%s用来输入一个字符串并存在字符数组里**。%c能够识别空格和换行符,而%s通过空格或换行来识别字符串的结束。** 另外,scanf在使用%s时,后面对应数组名前面是不用加&地址运算符的。
getchar输入、putchar输出
getchat\putchar分别用来输入、输出单个字符

#include<cstdio>
#include<cstring>
using namespace std;
int main (){
	char str[5][5];
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			str[i][j]=getchar();
		}
		getchar();//这句话是把末尾的换行符吸收掉 
	}
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			putchar(str[i][j]);
		}
		putchar('\n');
	}
	return 0;
} 

//gets输入,puts输出
gets用来输入一行字符串,(注意:gets识别换行符\n作为结束标志,因此scanf完一个整数后,如果要使用gets,需要先用getchar接收整数后的换行符),并将其存放在数组中。puts用来输出一行字符串,即将一维数组(或者二维数组的一维)在界面上输出,并跟着换行。
(3)字符数组的存放方式
在一维的字符数组的数组都有一位空字符\0,以表示存放字符串的结尾。空字符在gets或scanf输入字符串时自动添加的,并占用一个字符位,而puts和printf就是通过识别\0作为字符串的结尾输出的
特别提醒1:空字符的ASCII码为0,即空字符NULL,占用一个字符位,因此开数组时至少多一。 int型数组不需要,只有char数组需要\0与空格不是一个东西,空格ASCII为32.
特别提醒2:如果不是使用scanf函数的%格式或者gets函数输入字符串(例如使用getchar),切记一定要在字符串后面加上\0,否则printf或者puts因无法识别而导致后面出现乱码。
2.5.6 cstring头文件
cstring包含了许多用于字符数组的函数。
(1)strlen()函数
可以得到字符数组中第一个\0前的字符的个数。
strlen(字符数组);
(2)strcmp函数
strcmp函数结果返回两个字符串大小的比较结果,比较原则按照字典序。
strcmp(字符数组1,字符数组2);
若字符数组1<字符数组2,则返回一个负整数。
若字符数组1=字符数组2,则返回0.
若字符数组1>字符数组2,则返回一个正整数。
(3)strcpy()
把一个字符串复制给另一个字符串。(包括结束符)
strcpy(字符数组1,字符数组2);
(4)strcat()
把一个字符串接到另一个字符串的后面
strcat(字符数组1,字符数组2) //2接到1后面
2.5.7 sprintf与sscanf
scanf其实是把屏幕上的内容传到n中(即从左到右)
printf其实是把n中的内容传到屏幕上(即从右到左)
sscanf、sprintf格式与上面相同,只是将屏幕变成str.

2.6 函数
2.6.1函数的定义
:实现一个功能的语句的集合
有参函数:
无参函数:
全局变量:指在定义之后所有程序都有效
局部变量:指在函数内部生效,函数结束变量销毁
函数定义小括号内为形参,而实际调用小括号的参数成为实参
2.6.2再谈main函数
无论主函数在什么位置,整个程序一定从main先开始。
2.6.3以数组为函数参数
函数的参数也可以是数组,且数组作为参数时,第一维不需要填写长度。更重要的是,函数中对数组修改,就等于对原函数修改。

#include<cstdio>
#include<cstring>
using namespace std;
void change(int a[],int b[][5]){
	a[0]=1;
	a[1]=3;
	a[2]=5;
	b[0][0]=1;
}
int main (){
	int a[3]={0};
	int b[5][5]={0};
	change(a,b);
	for(int i=0;i<3;i++){
		printf("%d\n",a[i]);
	}
	return 0;
} 

虽然数组可以作为参数,但却不允许作为返回类型出现。
2.6.4 函数的嵌套调用
函数的嵌套调用是指在一个函数调用另一个函数,调用方式与主函数调用其他函数一样。
2.6.5函数的递归调用
指一个函数调用函数自身
2.7指针
2.7.1什么是指针
每个变量都会存放在内存中分配的一个空间 ,每种类型所占空间又不一样。int型占4Byte,long long 型占8Byte。每个字节(房间)就有一个地址(房间号),而计算机就是通过地址找变量。而用“指针”表示内存地址(或者指针指向内存地址)。
2.7.2指针变量
指针变量用来存放指针(或理解成地址),这个关系就跟int型变量存放int型常量。
另外,如果一次有好几个同种类型的指针变量要同时定义,星号只会跟第一个变量名。

int *p,q;

p是int 型,q是int 型
//int 是指针变量的类型,而后面的p才是变量名,用来存储地址。因此地址&a是赋给p而不是p
//那么对一个指针变量存放的地址,如何得到所指的元素呢?其实还是用到了星号
。可把星号*当成开启一个房间的钥匙

#include<cstdio>
using namespace std;
int main (){
	int a;
	int *p=&a;
	a=233;
	printf("%d\n",*p);
	return 0;
}
指针变量可以进行加减法。
p+1就是p所指int型变量的下一个int型变量地址。
指针变量支持自增、自减

2.7.3指针与数组
数组a的首地址为&a[0].
数组名称也作为数组的首地址使用。即a==&a[0];
a+i就是a首地址偏移i个int型变量的位置
*(p+i)a[i];
2.7.4使用指针变量作为函数参数
这视为将变量的地址传给函数。
2.7.5引用
引用不产生副本,就是给原变量产生了一个别名,对引用变量操作就是对原变量操作。
由于引用是变量的别名,因此常量不使用引用。
2.8结构体的使用
访问结构体有两种方法:“.”和“->”操作。
2.8.3结构体的初始化
2.9补充
2.9.2浮点数的比较
(1)等于运算符:如过a落在了[b-eps,b+eps]在区间中时,就说a
b。eps定义为1e-8
(2) 大于运算符:a-b>eps;
(3)小于运算符:a-b<-eps;
(4)大于等于运算符:
(5)小于等于运算符:
(6)Π

const double eps=1e-8;
const double Pi=acos(-1.0);
#define Equ(a,b) ((fab((a)-(b)))<(eps));
#define More(a,b) (((a)-(b))>(eps));
#define Less(a,b) (((a)-(b))<(-eps));
#define MoreEqu(a,b) (((a)-(b))>(-eps));
#define LessEqu(a,b) (((a)-(b))<(eps));

2.9.3 复杂度
1.时间复杂度
高等级的幂次会覆盖低等级的幂次
对数复杂度一般忽略其底数
对于一般的oj,一秒钟能承受10的7次方到10的八次方
2.空间复杂度
和时间复杂度类似,空间复杂度也是相同的写法,表示算法消耗最大的数据空间。
3.编码复杂度
定性的概念,代码量
2.10 黑盒测试
2.10.1单点测试
对于单点测试来说,系统会判断每组数据的输出结果是否正确。如果输出正确,那么对该组数据就算通过测试,并获得这组数据的分值。
2.10.2 多点测试
多点测试要求程序一次运行所有数据,并且所有数据都必须完全正确,这道题才算通过。
(1)while-EOF型
如果题目没有给定结束条件,那么就默认读取到文件末尾。
scanf函数的返回值就是成功读入参数的个数

while(scanf("%d",&n)!=EOF){
	
}

(2)while-break型
如果题目要求输入的数据满足某个条件就停止输入

while(scanf("%d%d",&a,&b)!=EOF){
	if(a==0&&b==0)
	break;
}

另一种简单的方法

while(scanf("%d%d",&a,&b),a||b){
	
}

(3)while(T–)型
题目中会给测试的组数,然后才能给出相应的输入数据。

int main (){
	int T;
	int a,b;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&a,&b);
	}
}

以上就是常见的输入类型,下面是输出类型
(1)正常输出:
(2)每组数据输出都会有额外加一个空行
(3)两组中间有一个空行,最后一组没有空行。

     与之类似的是,输出一行N个整数,每两个整数用空格隔开,最后一行不允许加空格
for(int i=0;i<n;i++){
	printf("%d",a[i]);
	if(i<n-1)
	printf(" ");
	else
	printf("\n"); 
}

在多点测试中,重置数组和变量。
重置数组一般用memset或者fill函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值