算法笔记学习(一)

今日目标:第二章结束(回顾浏览)

需要注意的点:

  1. iostream流和cstdio 不要混用,意思就是输入用cin,输出就用cout,不要scanf,cout混用,有时会出现问题,scanf,printf的效率会比cin,cout快。
  2. 变量类型需要记住,这是一个很重要的知识点P7页,float的精度大概为6到7位,double的精度为15到16位。
  3. 绝对值在10^9范围以内的整数都可以定义为int型。
  4. 整数取值范围超过2147483647(10^10或者10^18),就得用longlong型来存储。(意思是超过10^10不超过10^18)
  5. unsigned int 取值范围2^31-1,unsigned代表的是无符号类型,无符号类型一般代表的是正数,有符号类型代表的是正负数,符号位为1代表负数。
  6. 注意精度的要求,对于浮点型,不要使用float,一律使用double来存储,因为double的精度要求高15到16位。输入的话float用%f,double 用 %f,float和double输出都用%f。
  7. 在c++中,bool类型可以直接使用,但是在c语言中必须添加stdbool.h头文件才可以使用。
  8. 尽量不要使用宏定义来做除了定义常量以外的事情,除非给能加的地方都加上括号。具体样例看第13页。
  9. 运算符使用时注意除法的情况,i++是先使用i再将i加1,而++i则是先将i加1再使用i。
  10. const inf=0x3fffffff        和        const int inf=(1<<30)-1。是等价的,(必须加括号,因为位运算的优先级没有算术运算符高)
  11. getchar用来输入单个字符,putchar用来输出单个字符。
  12. floor 向下取整  floor(double x)用于double类型的向下取整,当然int类型也可以。ceil用于向上取整。
  13. 算法笔记学习(一)_第1张图片
  14.  sqrt求double类型的算术平方根,log(double x)求的是以自然对数为底的对数。c语言中没有对任意底数求对数的函数,因此必须使用换底公式来将不是以自然对数为底的对数转换为以e为底的对数,即logab=logeb/logea(p26页)。
  15. round(double x)用于将变量x四舍五入。
  16. if(n)相当于if(n!=0)             if(!n)相当于if(n==0)
  17. switch后面的每个分支语句结束后一定要带上break,不然会出现异常。
  18. do……while……会先执行循环体一次,然后才去判断循环体条件是否为真,这使得do……while……的实用性远不如while语句。  continue:结束当前循环         break:需要的场合直接退出循环
  19. 冒泡排序的实质:冒泡n-1躺,每次把最大的数放在最右边。n个数就要冒泡n-1趟,第i趟时从a[0]到a[n-i-1]都与它们下一个数比较。
  20. 如果数组大小较大(大概10^6级别),则需要将其定义在主函数外面,否则会使程序异常退出,原因是系统内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大。
  21. 注意memset和fill函数的区别,什么时候要用memset,什么时候要用fill。这都是要注意的点。
  22. getchar//putchar  输入和输出单个字符                  gets:输入一行字符串(gets识别“\n”作为输入结束)  puts:输出一行字符串,并紧跟一个换行。
  23. 在一维字符数组(或者二维数组的第二维)的末尾都有一个空字符\0,以表示存放的字符串的结尾。空字符\0在使用gets或者scanf输入字符串时会自动添加在输入的字符串后面,并占用一个字符位,而puts和printf就是通过识别\0作为字符串的结尾来输出的。
  24. 结束符\0的ASC||码为0,即空字符NULL,占用一个字符位,因此开字符数组的时候千万要记得字符数组的长度一定比实际储存字符串的长度至少多1.注意:int型数组的末尾不需要加\0,只有char类型需要。\0和空格不是一个东西,空格的ASCII码值是32,而\0的ACII码值为0.
  25. strcmp函数返回两个字符串大小的比较结果,比较原则是字典序。strcmp(str1,str2)==0说明字符串1和字符串2相等。strcmp(str1,str2)>0说明字符串数组1>字符串数组2,例如aaab>aaaaaa。 strcmp(str1,str2)<0说明字符串数组1<字符串数组2,例如aaaa>aaac。
  26. strcpy(str1,str2)是把str2复制给str1,这里的复制包含了结束符\0。strcat(str1,str2)是指把str2拼接到str1的后面。
  27. sscanf(str,"%d",&n)   是指把字符数组str中的内容以"%d"的格式写到n中,sprintf(str,"%d",n)的作用是把n以"%d"的格式写到str字符数组中,sscanf还支持正则表达式。
  28. 注意形参和实参的区别,函数的参数也可以是数组,且数组作为参数时,参数中数组的第一维不需要填写长度,如果是二维数组,那么第二维需要填写长度,实际调用时也只需要填写数组名,数组作为参数时,在函数中对数组元素的修改就等同于对原数组元素的修改(者与普通的局部变量不同)。

指针(讲的特别清楚,晴神)

​​​​​​​指针就是变量的地址,指针是一个unsigned类型的整数。 int* p1,p2代表的是p1是int* 型的,p2是int型的。如果两个都想写成int*型的,应该写为int *a,*b;这样才是正确操作。

指针变量用来存放指针(或者可以理解成地址),指针变量存放的是地址,而&则是取地址运算符,因此给指针变量赋值的方式一般是把变量的地址取出来,然后赋给对应类型的指针变量。

tips:指针变量和指针的区别:指针就是地址,地址就是指针。指针变量是一个变量,它保存了基本类型变量的地址。不懂也没关系,好多参考书里面是没有很明显的区分的。不过网上好多大佬对这个做了区分,具体百度。

int a; int* p;p=&a;int*是指针变量的类型,不是指针变量,这是一个误区,后面的p才是变量名,用来存储地址,因此&a是赋值给p的,而不是赋值给*p的。注意*是类型的一部分,不是指针变量。

int* p=&a,指针变量p存放了a的地址,为了通过p来获得变量a,可以把*视为一把开启房间的钥匙,将其加在p的前面,这样*p就可以把房间打开。

算法笔记学习(一)_第2张图片

代码解释:指针变量p存放的是a的地址,a的房间号里面的东西被改变了(a赋值给233),但这并不影响它的地址,而后在后面的输出中,使用*作为开启房间的钥匙,放在了p的前面,这样就获取到房间内的东西,即存储的数据。p保存的是地址,*p保存的是这个地址中存放的元素。指针变量可以进行加减法,其中减法的结果就是两个地址偏移的距离,对一个int*型的指针变量p来说,p+1代表的就是p所指的int型变量的下一个int型变量地址。指针变量支持自增和自减操作。

对指针变量来说,把其存储的地址的类型称为基类型,例如定义int* p的指针变量,int就是它的基类型。基类型必须和指针变量存储的地址类型相同,也就是说,上面定义的指针变量p不能够存放double型或char型数据的地址,而必须是int型数据的地址。

算法笔记学习(一)_第3张图片

代码解释:p存放的是&a[0]的地址,q存放的是&a[5]的地址,q-p就是指两个地址之间的距离,而这个距离是以int为单位。由于1个int占用4byte,因此实际上两个指针之间的距离就是20/4=5,因此输出的是5而不是20,其实归纳下,两个int型的指针相减,等价于在求两个指针之间相差了几个int,由于&a[0]和&a[5]之间相差了5个int,因此输出5.

P67P68还有两个经典例子,是特别经典的,一定要再次阅读

引用

注意区分引用的&和取地址运算符的&.

引用不产生副本,能达到修改传入参数的目的。指针修改传入参数会产生副本。

不管是否引用,函数的参数名和实际传入的参数名可以不同。 引用是产生变量的别名,因此常量不可使用引用。

结构体

结构体在c和c++中是不同的,一般写结构体最好按照字节顺序从大到小或者从小到大书写,避免空间的浪费。

结构体里面能定义除了自己本身(这样会引起循环定义的问题)之外的任何数据类型。不过不能定义自己本身,但可以定义自身类型的指针变量。结构体的初始化一般可以采用构造函数的方法。

1.在c++中,用结构体定义变量不需要加struct,而c中不行。

2.在C++中,可以定义空结构体,大小为1,而C中不行。

3.在C++中,可以在结构体声明中声明甚至实现函数,在C中只能放函数指针。

4.在C++中,成员函数直接可以访问本结构的成员变量而无需传入,在C中,函数和结构并无直接关联。

***成员函数不影响结构体的大小

因为成员函数是放在公共区域的,只是在这个结构体域中而已。 

补充说明

cout 控制精度:如果要输出小数点后两位,那么头文件需要变为#include

cout<

如何判断两个数是否相等呢?不能仅仅通过基础的if语句if(a==b)来判断相等。这样做不符合精度的要求。如果一个数a落在了[a-eps,a+eps]的范围,则能表明a==b,那么eps取值多少呢?根据经验表示eps=10^(-8),eps取10^(-8)对大多数的情况既不会漏判,也不会误判。 const double eps=1e-8;

const double eps=1e-8;
const double pi=acos(-1.0);
#define Equ(a,b)((fabs((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))

就是这样使用,一般出题判断大小这就是坑点。对于一般的OJ系统来说,一秒能承受的运算次数大概是10^7---10^8。因此如果O(n^2)的算法当n的规模为1000时是可以承受的,而当n的规模为1000000则承受不了,因此数据量很大时,时间复杂度显得尤为重要。

你可能感兴趣的:(算法笔记学习笔记)