《算法笔记》学习笔记 part1

一.  前言

    我开始写这篇笔记时,2019年研究生考试已经过去一周了,虽然还不知道初试结果,但还是要开始准备复试了。复试中机试又占了很大的比例,故这里开始复习算法知识了,主要用书为《算法笔记》。

    这份笔记将主要分两个部分。本篇笔记为part1。主要包括两个内容,一是我觉得有必要记录的知识点;另外就是一些专题,内容是一些归纳和自己的思考。

    希望能顺利的通过复试(如果过了初试的话...)

二.  知识点部分

【引】这里记录一些小知识点

1.变量类型范围问题:简单来说,看到题目要求10的9次方以内时,用int;若是10的18次方以内,用long long。其中大于2^31-1的话就要再在数值后加上LL。另外,对于浮点型,根本不要用float,直接上double。

2.字符与ASCII:小写字母比大写字母的ASCII码值大32,eg:a为97,A为65。另外,字符在计算机内部就是按照ASCII码来存储的,所以char c = 97这句话就相当于char c = 'a'。还要注意大小写怎么转换,其实就是加或减32的问题,当然也可以用toupper()和tolower(),需要iostream的头函数(其实是ctype)

3.定义常量的两种方式:eg1:#define pi 3.14    eg2:const double pi = 3.14。

【注】p13“宏定义陷阱”,如define Add(a, b)  ((a)+(b)),具体不赘述,总之就是要加上尽可能多的括号。

4.位运算符:见下图

5.Scanf中用到的“&”:变量在定义后,会在计算机内存中分配一块空间给这个变量,为了得到这个变量的地址,需要加上这个&。其他还需提醒的在下图中:

【注】除了%c之外,scanf对其他格式符的输入是以空白符(空格,换行等)为结束判断标志的。举个例,看下面这段代码:

由于字符可以读入空格和换行,所以空格被当作了c的值,而str会把空格当作结束,所以a就成了str。

6. %md, %0md, %.mf的作用(p22)

7.一些常用math函数

         floor(x):向下取整       ceil(x):向上取整

         pow(a, b):求a的b次方  sqrt(x):求根号

         log(x):即求lnx,若要求以a为底的,则必须利用公式:lnb/lna 来替换

         pi的精确定义为acos(-1.0)

8.while和do...while:后者会先执行循环体一次,再去判断循环条件是否为真,这就使得其实用性不如前者。

9.对于一个很大的数组(10^6级别),则需要将其定义在主函数外面,否则会异常退出。

10.memset:对于一个数组(如{1,2,3,4,5}),可利用memset(a, 0, sizeof(a))这句代码来让所有元素值置0,注意使用这个函数最好只把值置为0或-1,具体原因见p46

11.字符数据输入输出三种方式:

scanf & printf

注意输入时,%c能识别空格和换行并将其输入,而%s则将其当作结束

getchar & putchar用以输入输出单个字符
gets & puts用以输入输出一行字符串。注意gets()会将\n作为输入结束,所以scanf完一个整数后,若要用gets,需先用getchar接收整数后的换行符。

 

 

 

 

【注1】由于字符串结束符\0ASCII码为0,占用一个字符位,因此开字符数组时千万记得字符数组长度一定要比实际存储字符串长度至少多1个。

【注2】若不是使用scanf(%s格式)或gets输入字符串,则一定要在输入字符串后加'\0',不然printf或puts输出会无法识别字符串末尾而导致输出乱码。

12.string.h含有的几个函数

strlen()得到字符数组的长度(不算'\0')
strcmp()返回两个字符串大小的比较结果(按照字典序)
strcpy()字符串复制,eg:strcpy(str1, str2),即把1复制到2
strcat()把一个字符串接到另一个字符串后面,eg:strcat(str1, str2),注意是把2接到1之后

 

 

 

 

13.sscanf和sprintf:这两个是处理字符串问题的利器,具体可见p53-54,这里贴两个例子:

14.以数组作为函数参数要注意的点:首先是参数中数组的第一维不需要填写长度,若是二维,则第二维需填写;其次,当数组作为参数时,在函数中对数组元素的修改相当于是对原数组元素的修改,这一点和普通局部变量不同。

15.关于STL,实在是为我们省了很多力气。STL里的容器就像是Python里的列表,字典,元祖,集合这四种基本数据结构一样,可以方便的解决很多问题。这部分内容由于很多,我就只列出《算法笔记》上说到的一些方法吧:

容器简介常用函数(i一般指值,it一般指迭代器)
vector变长数组,长度根据需要自己变化;一般用于在元素个数不确定时节省空间push_back(x):在最后添加一个元素
pop_back(x):删除尾元素
size():获取长度
clear():清除所有
insert(it, x):在it处插入x
erase(it):删除it处的元素(erase有多种删除方式)
set就是个集合insert(x):插入x
find(value):找值为value的迭代器
erase(it):删除it处的元素(erase有多种删除方式)
size():获取长度
clear():清除所有
string专门用于字符串处理的容器,好用的很!string之间可以直接加减,比较
length()/size()
insert(pos, string):在pos号位置插入string(还有其他写法)
erase(it):删除it处的元素(erase有多种删除方式)
clear():清除所有
substr(pos, len):返回从pos开始长为len的子串
string::npos:find()失配时的默认值
find(str2):找字串str2的初始位置(有多种写法)
replace(pos, len, str2):把str从pos开始,长为len的字串替换为str2(有多种写法)
map就是个字典find(key):找到key的迭代器
erase(it):删除it处的元素(erase有多种删除方式)
size():获取长度
clear():清除所有

三.  专题部分

专题一:类型转换

【引】在刷题过程中遇到过很多需要将“数字”,“字符”,“字符串”这三种类型互相转换,故这里做个小结。

1.string --> char数组(如果要使用printf输出,那么string必须先转化为char数组)

string b;

printf("%s", b.c_str())

2.char数组 --> string (这个倒是不常用,我处理字符串现在基本用string了,但还是记录一下)

char a[] = "haha";
string b(a);  //直接初始化

3.数字 --> 字符(这个之前提过,就是+‘0’和-‘0’的事情)

4.数字 --> 字符串(我现在大致有两种方法,如下:)

//法一
int a = 123;
string b;
stringstream ss;
ss << a;
b = ss.str();

//法二(只能是int --> char数组)
int a = 123;
char b[10] = {0};  //注意这个数组长度需稍微设置大一些,不然报错
itoa(a, b, 10); //a为需转换的值,b为转换后放的地址,10为10进制的意思

5.字符串 --> 数字(同样有两种方法,如下:)

//法一
string a = "123";
int b;
stringstream ss;
ss << a;
ss >> b;

//法二
char a[] = "123";
int b = atoi(a);

【注】需注意的是,itoa和atoi都是针对整型和字符串的,如果是浮点型,那就是ftoa和atof。另外,对于stringstream ss要注意,如果你要用到它不止一次,在使用一次之后需要使用ss.clear(); ss.str(""); 清空缓冲区(这两个函数最好一起用)

专题二:数学问题

1.素数:主要了解如何判断一个数字是否是素数。

bool is_Prime(int n){
	if(n <= 1) return 0;
	int sqr = (int)sqrt(n * 1.0);
	for(int i=2; i<=sqr; i++)
		if(n % i == 0)
			return 0;
	return 1;
}

【注】埃式筛法也不难,但是感觉一般用不到。(算法笔记p162)

2.最大公约数:记住gcd(a, b) = gcd(b, a%b);

int gcd(int a, int b){
    if(b == 0)
        return a;
    else
        return gcd(b, a % b);
}

3.分数:关于分数最重要的就是3条规则,如下代码(其中列出了减法的代码,加,减,乘均类似)

int gcd(int a, int b){
	if(b==0) return a;
	return gcb(b, a % b);
}

struct Fraction{
	int up, down;//分子 分母
};

Fraction reduction(Fraction res){
	if(res.down < 0){//规则1:负号只放在分子
		res.down = -res.down;
		res.up = -res.up;
	}
	if(res.up == 0)//规则2:分母不为0
		res.down = 1;
	else{
		int k = gcd(abs(res.up), abs(res.down));//规则3:化简(分子分母没有1之外的公约数),注意abs
		res.up /= k;
		res.down /= k;
	}
	return res;
}

Fraction minu(Fraction a, Fraction b){ //分数减法
	Fraction res;
	res.up = a.up*b.down - a.down*b.up;
	res.down = a.down * b.down;
	return reduction(res);
}

4.进制转换:掌握将P进制转化为10进制,以及10进制转化为Q进制即可。(算法笔记P93)

5.复数运算:参考(https://blog.csdn.net/qq_35194071/article/details/82014561

6.大整数运算:对于大整数就需要用int数组来存每一位。

 

专题三:排序

【引】这里我先把在复习数据结构时做的九大排序的表格列出来,可以说是一目了然了。

1.冒泡排序

#include <cstdio>
int main(){
    int a[10] = {3,2,4,3,7,5,8,6,0,10};
    for(int i=1;i<10;i++){    //这里要注意i因为是第几趟的含义,要从1开始
        for(int j=0;j<10-i;j++){
            if(a[j] > a[j+1]){
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
    for(int i=0;i<10;i++)
        printf("%d\n", a[i]);
}

  • 12
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在有关算法的书中,有一些叙述非常严谨,但不够全面;另一些涉及了大量的题材,但又缺乏严谨性。本书将严谨性和全面性融为一体,深入讨论各类算法,并着力使这些算法的设计和分析能为各个层次的读者接受。全书各章自成体系,可以作为独立的学习单元;算法以英语和伪代码的形式描述,具备初步程序设计经验的人就能看懂;说明和解释力求浅显易懂,不失深度和数学严谨性。 --------------------------------------------------------------- 目录 Introduction to Algorithms, Third Edition 出版者的话 译者序 前言 第一部分 基础知识 第1章 算法在计算中的作用  1.1 算法  1.2 作为一种技术的算法  思考题  本章注记 第2章 算法基础  2.1 插入排序  2.2 分析算法  2.3 设计算法   2.3.1 分治法   2.3.2 分析分治算法  思考题  本章注记 第3章 函数的增长  3.1 渐近记号  3.2 标准记号与常用函数  思考题  本章注记 第4章 分治策略  4.1 最大子数组问题  4.2 矩阵乘法的Strassen算法  4.3 用代入法求解递归式  4.4 用递归树方法求解递归式  4.5 用主方法求解递归式  4.6 证明主定理   4.6.1 对b的幂证明主定理   4.6.2 向下取整和向上取整  思考题  本章注记 第5章 概率分析和随机算法  5.1 雇用问题  5.2 指示器随机变量  5.3 随机算法  ?5.4 概率分析和指示器随机变量的进一步使用   5.4.1 生日悖论   5.4.2 球与箱子   5.4.3 特征序列   5.4.4 在线雇用问题  思考题  本章注记 第二部分 排序和顺序统计量 第6章 堆排序  6.1 堆  6.2 维护堆的性质  6.3 建堆  6.4 堆排序算法  6.5 优先队列  思考题  本章注记 第7章 快速排序  7.1 快速排序的描述  7.2 快速排序的性能  7.3 快速排序的随机化版本  7.4 快速排序分析   7.4.1 最坏情况分析   7.4.2 期望运行时间  思考题  本章注记 第8章 线性时间排序  8.1 排序算法的下界  8.2 计数排序  8.3 基数排序  8.4 桶排序  思考题  本章注记 第9章 中位数和顺序统计量  9.1 最小值和最大值  9.2 期望为线性时间的选择算法  9.3 最坏情况为线性时间的选择算法  思考题  本章注记 第三部分 数据结构 第10章 基本数据结构  10.1 栈和队列  10.2 链表  10.3 指针和对象的实现  10.4 有根树的表示  思考题  本章注记 第11章 散列表  11.1 直接寻址表  11.2 散列表  11.3 散列函数   11.3.1 除法散列法   11.3.2 乘法散列法   11.3.3 全域散列法  11.4 开放寻址法  11.5 完全散列  思考题  本章注记 第12章 二叉搜索树  12.1 什么是二叉搜索树  12.2 查询二叉搜索树  12.3 插入和删除  12.4 随机构建二叉搜索树  思考题  本章注记 第13章 红黑树  13.1 红黑树的性质  13.2 旋转  13.3 插入  13.4 删除  思考题  本章注记 第14章 数据结构的扩张  14.1 动态顺序统计  14.2 如何扩张数据结构  14.3 区间树  思考题  本章注记 第四部分 高级设计和分析技术 第15章 动态规划  15.1 钢条切割  15.2 矩阵链乘法  15.3 动态规划原理  15.4 最长公共子序列  15.5 最优二叉搜索树  思考题  本章注记 第16章 贪心算法  16.1 活动选择问题  16.2 贪心算法原理  16.3 赫夫曼编码  16.4 拟阵和贪心算法  16.5 用拟阵求解任务调度问题  思考题  本章注记 第17章 摊还分析  17.1 聚合分析  17.2 核算法  17.3 势能法  17.4 动态表   17.4.1 表扩张   17.4.2 表扩张和收缩  思考题  本章注记 第五部分 高级数据结构 第18章 B树  18.1 B树的定义  18.2 B树上的基本操作  18.3 从B树中删除关键字  思考题  本章注记 第19章 斐波那契堆  19.1 斐波那契堆结构  19.2 可合并堆操作  19.3 关键字减值和删除一个结点  19.4 最大度数的界  思考题  本章注记 第20章 van Emde Boas树  20.1 基本方法  20.2 递归结构   20.2.1 原型van Emde Boas结构   20.2.2 原型van Emde Boas结构上的操作  20.3 van Emde Boas树及其操作   20.3.1 van Emde Boas树   20.3.2 van Emde Boas树的操作  思考题  本章注记 第21章 用于不相交集合的数据结构  21.1 不相交集合的操作  21.2 不相交集合的链表表示  21.3 不相交集合森林  *21.4 带路径压缩的按秩合并的分析  思考题  本章注记 第六部分 图算法 第22章 基本的图算法  22.1 图的表示  22.2 广度优先搜索  22.3 深度优先搜索  22.4 拓扑排序  22.5 强连通分量  思考题  本章注记 第23章 最小生成树  23.1 最小生成树的形成  23.2 Kruskal算法和Prim算法  思考题  本章注记 第24章 单源最短路径  24.1 Bellman?Ford算法  24.2 有向无环图中的单源最短路径问题  24.3 Dijkstra算法  24.4 差分约束和最短路径  24.5 最短路径性质的证明  思考题  本章注记 第25章 所有结点对的最短路径问题  25.1 最短路径和矩阵乘法  25.2 Floyd?Warshall算法  25.3 用于稀疏图的Johnson算法  思考题  本章注记 第26章 最大流  26.1 流网络  26.2 Ford\Fulkerson方法  26.3 最大二分匹配  26.4 推送重贴标签算法  26.5 前置重贴标签算法  思考题  本章注记 第七部分 算法问题选编 第27章 多线程算法  27.1 动态多线程基础  27.2 多线程矩阵乘法  27.3 多线程归并排序  思考题  本章注记 第28章 矩阵运算  28.1 求解线性方程组  28.2 矩阵求逆  28.3 对称正定矩阵和最小二乘逼近  思考题  本章注记 第29章 线性规划  29.1 标准型和松弛型  29.2 将问题表达为线性规划  29.3 单纯形算法  29.4 对偶性  29.5 初始基本可行解  思考题  本章注记 第30章 多项式与快速傅里叶变换  30.1 多项式的表示  30.2 DFT与FFT  30.3 高效FFT实现  思考题  本章注记 第31章 数论算法  31.1 基础数论概念  31.2 最大公约数  31.3 模运算  31.4 求解模线性方程  31.5 中国余数定理  31.6 元素的幂  31.7 RSA公钥加密系统  31.8 素数的测试  31.9 整数的因子分解  思考题  本章注记 第32章 字符串匹配  32.1 朴素字符串匹配算法  32.2 Rabin\Karp算法  32.3 利用有限自动机进行字符串匹配  32.4 Knuth?Morris?Pratt算法  思考题  本章注记 第33章 计算几何学  33.1 线段的性质  33.2 确定任意一对线段是否相交  33.3 寻找凸包  33.4 寻找最近点对  思考题  本章注记 第34章 NP完全性  34.1 多项式时间  34.2 多项式时间的验证  34.3 NP完全性与可归约性  34.4 NP完全性的证明  34.5 NP完全问题   34.5.1 团问题   34.5.2 顶点覆盖问题   34.5.3 哈密顿回路问题   34.5.4 旅行商问题   34.5.5 子集和问题  思考题  本章注记 第35章 近似算法  35.1 顶点覆盖问题  35.2 旅行商问题  35.2.1 满足三角不等式的旅行商问题  35.2.2 一般旅行商问题  35.3 集合覆盖问题  35.4 随机化和线性规划  35.5 子集和问题  思考题  本章注记 第八部分 附录:数学基础知识 附录A 求和  A.1 求和公式及其性质  A.2 确定求和时间的界  思考题  附录注记 附录B 集合等离散数学内容  B.1 集合  B.2 关系  B.3 函数  B.4 图  B.5 树   B.5.1 自由树   B.5.2 有根树和有序树   B.5.3 二叉树和位置树  思考题  附录注记 附录C 计数与概率  C.1 计数  C.2 概率 C.3 离散随机变量  C.4 几何分布与二项分布  *C.5 二项分布的尾部  思考题  附录注记 附录D 矩阵  D.1 矩阵与矩阵运算  D.2 矩阵基本性质  思考题  附录注记

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值