本学习笔记是根据《算法零基础100讲》进行的每讲总结,目标是采用刻意练习的方法对个人的学习和思考进行总结和归纳,方便复习和进一步深入理解和掌握内化。
每一讲的笔记内容大致分为三个部分:
- 设问,通过这一讲的学习应该理解什么内容?
- 题目,在学习完每讲内容后对题目先进行独立的思考和分析,记录下来;
- 题解报告,通过个人思考和学习其他优秀解题方案,记录个人认为较为优秀的解答并进行画图理解和内化吸收,并分析如何优化自己的思考;
- 知识点笔记,将本讲内容的知识点进行汇总和扩展,方便日后查阅复习;
- 解题模板,尽量将所学代码进行通用化处理。
另外:
笔记中会尽量用图示的方式将所学内容进行可视化,方便记忆和内化,以及帮助读者进行理解。
笔记至少会参考5篇以上的参考资料,并在文尾列出。
第一讲:幂和对数
一、设问
- C语言关于幂和对数的库函数是哪些?使用的注意点有哪些?
- 幂和对数有何关系?对数思想的用处是什么?
- 整数在计算机中是如何存储的?
- 如何通过位运算和mask准确把握整数的二进制位是否为1?
- C语言中如何存储浮点数?
- C语言的+ - * / 会对精度有何影响?其时间复杂度又如何?
- 如何实现高精度运算?
二、题目
这三道题都可以使用一样的思路即可解决:即判断对数和幂是否相等
同时还可以将数一直除以底,看最终的值是否为1
三、题解报告
bool isPowerOfx(int n, int base){
if (n < 1) {
return false;
}
int exp = (int)(log2(n)/log2(base) + 1e-8);
if (n == (int)pow(base, exp)) {
return true;
}
return false;
}
bool isPowerOfx(int n, int base){
if (n < 1) {
return false;
}
while (n % base == 0) {
n /= base;
}
return n == 1;
}
通用思路1:使用C库函数求得log值和幂值,然后判断是否相等。计算exp时 + 1e-8 是为了防止精度损失
通用思路2:一直除以base,直到无法整除,最终结果是否为1.
bool isPowerOfFour(int n){
if (n < 1) {
return false;
}
if ((n & (n - 1)) == 0) {
for (int i = 4; i <= n; i<<=2) {
printf("%d ", i);
if (i & n) {
return true;
}
}
}
return n == 1;
}
bool isPowerOfFour(int n){
if (n < 1) {
return false;
}
return (((n & (n - 1)) == 0
&& (n & 0xaaaaaaaa) == 0));
}
bool isPowerOfFour(int n){
return n > 0 && (n & (n - 1)) == 0 && n % 3 == 1;
}
4的幂在二进制表达中,只有一个1在某奇数位上。
n & (n - 1)可以确定是否为偶数/2的幂。
0xaaaaaaaa = (10101010101010101010101010101010) ,
是构造的每个奇数位均为0的mask,通过&上他,可以使奇数位上1变为0,因此与是2的幂组合起来可以判断是否为4的幂。
4的幂 %3 一定为1.
四、知识点笔记
“在计算机科学中,除非有特别的声明,所有的对数都是以2为底”
n m = n ∗ n ∗ . . . ∗ n ⏟ m 个 n a b = a b − − − − − − − − l o g n T = m ( i f T = n m ) − − − − − − − − X a X b = X a + b X a X b = X a − b ( X a ) b = X a b X n + X n = 2 X n ≠ X 2 n 2 n + 2 n = 2 n + 1 − − − − − − − − − − − l o g B A = l o g n A l o g n B ; C > 0 l o g A B = l o g A + l o g B l o g A / B = l o g A − l o g B l o g ( A B ) = B l o g A l o g x < x − − − − − − − − − − − − − l o g 1 = 0 , l o g 2 = 1 , l o g 1024 = 10 , l o g 1048476 = 20 n^m = \underbrace{n * n * ...*n}_{m个}\\ n^{\frac{a}{b}} = \sqrt[b]{a}\\ --------\\ log_n T = m (if \space T = n^m)\\ --------\\ X^aX^b = X^{a+b}\\ \frac{X^a}{X^b} = X^{a-b}\\ (X^{a})^{b} = X^{ab}\\ X^n + X^n = 2X^n \neq X^{2n}\\ 2^n + 2^n = 2^{n+1}\\ ----------- \\ log_B A = \frac{log_n A}{log_n B}; C > 0\\ log A B = logA + logB\\ logA/B = logA - logB\\ log(A^B) = B logA\\ logx < x\\ -------------\\ log1 = 0, log2 = 1, log1024 = 10, log1048476 = 20 nm=m个 n∗n∗...∗nnba=ba−−−−−−−−lognT=m(if T=nm)−−−−−−−−XaXb=Xa+bXbXa=Xa−b(Xa)b=XabXn+Xn=2Xn=X2n2n+2n=2n+1−−−−−−−−−−−logBA=lognBlognA;C>0logAB=logA+logBlogA/B=logA−logBlog(AB)=BlogAlogx<x−−−−−−−−−−−−−log1=0,log2=1,log1024=10,log1048476=20
-
-
double pow (double base, double exponent);
-
/* pow example */ #include <stdio.h> /* printf */ #include <math.h> /* pow */ int main () { printf ("7 ^ 3 = %f\n", pow (7.0, 3.0) ); printf ("4.73 ^ 12 = %f\n", pow (4.73, 12.0) ); printf ("32.01 ^ 1.54 = %f\n", pow (32.01, 1.54) ); return 0; }
-
-
-
double log (double x);
-
/* log example */ #include <stdio.h> /* printf */ #include <math.h> /* log */ int main () { double param, result; param = 5.5; result = log (param); printf ("log(%f) = %f\n", param, result ); return 0; }
-
-
-
double log10 (double x);
-
/* log10 example */ #include <stdio.h> /* printf */ #include <math.h> /* log10 */ int main () { double param, result; param = 1000.0; result = log10 (param); printf ("log10(%f) = %f\n", param, result ); return 0; }
-
- 对数(英语:logarithm)是幂运算的逆运算
- 对数思想简史:
- 计算机中使用幂和对数的概念存储数据(二进制数)
- C库函数中的pow、log2和log10函数的运行结果均为double类型,float类型的有效小数位为6位(第7位会受四舍五入的影响),double类型的有效小数位为15位(第16位受四舍五入的影响)
- 浮点数的存储方式为S-E-M, 即
(
−
1
)
S
∗
M
∗
2
E
(-1)^S * M * 2^E
(−1)S∗M∗2E,S为符号位,M为有效数字,E为指数为,使用科学计数法的方式进行存储。
- 对浮点数进行的操作越多,损失的精度就越大
- 位运算符的优先级低于逻辑运算符,如:&的优先级低于==
《算法零基础100讲》介绍
该栏目是CSDN@英雄哪里出来大佬的万人千题计划第一阶段,其目标是让想要学会算法的人抱团成长,能通过这个项目稳步成长,扎扎实实掌握算法,最终用算法改变世界!
大佬将算法学习的路线总结如下,并分别根据五步路线总结写出了相应的教学内容,关于目前的第一阶段算法入门的详细的介绍可以看博文《万人千题:第一阶段,算法零基础抱团打卡》学习路线指引
100讲的学习大纲如下:
参考资料
此处列出除文中链接之外的参考资料