Data Structures and Algorithm Analysis in c++ 第一章笔记和部分习题

注:输入问题懒得搞,
 A 表示A的X次方
 logA(B) 表示底数为A,真数为B
 加减乘除等 +-*/=

 
指数 exponent
 A * A = A
 A / A = A
 A = A
 A + A = 2 * A != A<2 * X>
 2 + 2 = 2 * 2 = 2<1 + X>
 
对数 Logarithms
 在计算机科学中,所有对数的底数默认为2
 
 定义:
  如果有 A = B,则有且仅有 logA(B) = X, 称 X为以 A为底 B的对数
  
 1:
  logA(B) = logC(B) / logC(A); A,B,C > 0, A!=1
  证明:
   假设
   Z = logA(B); ==>  A = B ==> 公式3
   X = logC(A); ==>  C = A ==> 公式1
   Y = logC(B); ==>  C = B ==> 公式2
   将公式1,2代入3得:
   ==> C = C
   ==> X * Z = Y
   ==> Y / X = Z;
   得证
   
 2:
  log(AB) = log(A) + log(B); A,B > 0
  证明:
   假设
   Z = log(AB); ==>  2 = AB ==> 公式3
   X = log(A); ==>  2 = A ==> 公式1
   Y = log(B); ==>  2 = B ==> 公式2
   将公式1,2代入3得:
   ==> 2 = 2 * 2
   ==> Z = Y + X;
   得证
   
 3:
  log(A/B) = log(A) - log(B); A,B > 0
  证明:
   假设
   Z = log(A/B); ==>  2 = A/B ==> 公式3
   X = log(A); ==>  2 = A ==> 公式1
   Y = log(B); ==>  2 = B ==> 公式2
   将公式1,2代入3得:
   ==> 2 = 2 / 2
   ==> Z = X - Y;
   得证
   
 4:
  log(A) = B * log(A); A,B > 0
  证明:
   假设
   Z = log(A); ==>  2 = A ==> 公式3
   X = log(A);  ==>  2 = A ==> 公式1
   将公式1代入3得:
   ==> 2 = 2
   ==> Z = X * B;
   得证
   
 5:
  log(X) < X; X > 0
  证明:
  0 < X <= 2时,
   log(X) <= 1
  2 < X 时,假设 log(X) < X 成立
   X + 1 = X + log(2) > log(X) + log(2) = log(2X) > log(X + 1)
   
级数 series
 常用求和公式:
  i[0,n], 2的求和: 2 - 1
   设:
    Sn = 1 + 2 + 2<2> +...+ 2
   等式两端乘以2:
    2*Sn = 2 + 2<2> + 2<3> +...+ 2
   两式相减
    Sn = 2 - 1
    
  i[0,n], A的求和: (A - 1) / (A - 1)
   设:
    Sn = 1 + A + A<2> +...+ A
   等式两端乘以A:
    A*Sn = A + A<2> + A<3> +...+ A
   两式相减
    (A - 1)Sn = A - 1
    Sn = (A - 1) / (A - 1)
   同理如果 当 0 < A < 1
    (1 - A)Sn <= 1
    Sn <= 1 / (1 - A)
    
  i[1,n], i/(2)的求和: Sn <= 2
   设:
    Sn = 1/2 + 2/4 + 3/8 +...+ n/(2)
   等式两端乘以A:
    2*Sn = 1 + 2/2 + 3/4 + 3/8 +...+ n/(2)
   两式相减
    Sn = 1 + 1/2 + 1/4 + ...
    Sn <= 2
    
  i[1,n], i<2>的求和: n(n+1)(2n+1)/6 约等于 n<3>/3
  
  i[1,n], i的求和: 约等于 n/(k + 1)
  
  i[1,n], 1/i的求和: 约等于 loge(n)
  
模运算 mod
 如果 A - B 被 N 整除,则无论 A 除以 N 或 B 除以 N,余数都相同,称AB同余,记作:A≡B(mod N),则 A + C 和 B + C 同余,A * C 和 B * C 同余
 对于 N 是一个素数(prime number, 仅能被 1 和 自身整除):
  1当且仅当 A≡0(mod N) 或 B≡0(mod N)时, AB≡0(mod N)
  2.Ax≡1(mod N),对于 0 < A < N ,x 有唯一解
  3.x<2>≡A(mod N), 对于 0 < A < N,有2个解或无解
  
数据结构与算法分析中,两种证明方法:归纳法(induction), 反证法(contradiction)
 归纳法(induction)
  首先证明基础情况(base case),就是确定一些较小数值成立
  接下来,(induction hypothesis)假设理论对于有限的K范围内的值都成立
  最后,利用假设证明对于 k+1,成立即可,k是有限的
  
  Fibonacci 数列: f(i) = f(i-1) + f(i-2), 用归纳法证明:满足 f(i) < (5/3)
   对于i = 1,2,3, f(i) = 1,1,2, 分别小于 5/3,25/9,125/27, base case 满足;
   假设对于 i = k, 满足 f(k) < (5/3)
   对于 i = k + 1:
    f(k + 1)  = f(k) + f(k-1)
    f(k + 1)  < (5/3) + (5/3)
    f(k + 1)  < (3/5)(5/3) + (3/5)(3/5)(5/3)
    f(k + 1)  < (5/3) * (3/5 + 9/25)
    f(k + 1)  < (5/3) * (24/25)
    f(k + 1)  < (5/3)
   得证
  
  i[1,n], i<2>的求和: n(n+1)(2n+1)/6
   假设对于 i = n, n<2>的求和为 n(n+1)(2n+1)/6
   对于 i = n + 1, (n + 1)<2> 的求和为:
    n(n+1)(2n+1)/6 + (n+1)<2>
    (n+1)*[n(2n+1)/6+(n+1)]
    (n+1)*[(2n<2> + 7n + 6)/6]
    (n+1)*[(2n+3)(n+2)/6]
    (n+1)(n+1+1)(2(n+1)+1)/6
   得证
   
递归 recursive
 1.必须存在不需要递归就可以求解的基本情况(base case)
 2.所有需要递归求解的情况,都必须最终归于(Making progress)一个基本情况
 3.design rule,假设所有的递归都正确
 4.Compound interest rule,对于同一个问题的同一个实例,绝不要在递归中重复工作
 
c++ 技巧:
 在类的构造函数中,如果参数是类类型,使用初始化列表(initialization list)优于赋值语句(assignment statement),使用初始化列表直接调用构造函数,赋值一般先构造临时对象,然后赋值
 
 
练习1.5:
 Write a recursive function that returns the number of 1 in the binary representation
 ofN. Use the fact that this is equal to the number of 1 in the representation ofN/2,
 plus 1, if N is odd.

 std::size_t last_bit(std::size_t n){
  if (n == 0)
   return 0;
  return (n & 1u) + last_bit(n >> 1u); //equal to n/2
 }

练习1.8
 1> i[0,n], 1/(4) 求和
  根据公式约等于 4/3
 2> i[0,n], i/(4) 求和
  Sn = 1/4 + 2/16 + 3/64 +....
  4*Sn = 1 + 2/4 + 3/16 + ...
  3*Sn = 1 + 1/4 + 1/16 = 4/3
  Sn = 4/9
 3> i[0,n], i/(4) 求和
  Sn = 1/4 + 4/16 + 9/64 + ...
  4*Sn = 1 + 4/4 + 9/16 + ...
  3*Sn = 1 + 3/4 + 5/16 + ... =  5 * i/(4) 求和 = 20/27
 
练习1.9
 i[1,n/2],1/i 求和
 ln(n) - ln(n/2 - 1) = ln(n) - ln(n/2) = ln2

练习1.10
 2<100> (mod 5) = 1
 2<4> (mod5) = 1
 2<100> = (2<4>)<25> = 1<25> = 1

练习1.11 不会...

练习1.12
 a> 证明i[1,n] 2i - 1 的求和等于 n<2>
  2(n + 1) - 1 + n<2> = n<2> + 2n +1 = (n+1)<2>


 b> 证明i[1,n] i<3> 的求和等于i[1,n] i 的求和的平方
  (n+1)<3> + (1+n)<2>*n<2>/4 = (n+1)<2> * (n/2 + 1)<2> = [(n+1)(n+1+1)/2]<2>
  
练习1.15 

//==================矩形类==================

#ifndef RECTANGLE_H
#define RECTANGLE_H

#include 

class Rectangle{
public:
	using sz = std::size_t;

	friend std::ostream & print(std::ostream &, const Rectangle &);
	Rectangle(sz w = 0, sz l = 0) : width(w), length(l){ }

	sz get_length() const {
		return length;
	}
	sz get_width() const {
		return width;
	}

private:
	sz width;
	sz length;
};

//show Rectangle's data members
std::ostream & print(std::ostream & os, const Rectangle & rc){
	return os << rc.get_length() << " - " << rc.get_width();
}

#endif // RECTANGLE_H	


//=================查找最大的函数模板===================

#ifndef FINDMAX_H
#define FINDMAX_H

#include 

template 
const Object & find_max(const std::vector & vo, comparer com){
	std::size_t sz = 0;
	for (std::size_t i = 1; i < vo.size(); ++i){
		if (com(vo[i], vo[sz]))
			sz = i;
	}
	return vo[sz];
}

#endif	//FINDMAX_H 
   


//=================两个比较面积和周长的函数对像模板===================

#ifndef COMPARING_H
#define COMPARING_H

//compare area
template 
class comparing_area{
public:
	bool operator()(const Object & rec1, const Object & rec2) const {
		return rec1.get_width() * rec1.get_length() > rec2.get_width() * rec2.get_length();
	};
};

//compare perimeter
template 
class comparing_perimeter{
public:
	bool operator()(const Object & rec1, const Object & rec2) const {
		return rec1.get_width() + rec1.get_length() > rec2.get_width() + rec2.get_length();
	};
};

#endif	//COMPARING_H

//===================使用上面定义的模板类=================

#include 
#include 
#include "Rectangle.h"
#include "Findmax.h"
#include "Comparing.h"

#define RANDOM(x) (std::rand()%x)

int main(){
	std::vector vr;
	std::size_t i = 0;
	std::srand(std::time(0));
	//generate a array of Rectangle by rand()
	while (i != 10){
		vr.push_back(Rectangle(RANDOM(10) + 1, RANDOM(10) + 1));
		//show Rectangle
		print(std::cout, vr[i]) << std::endl;
		++i;
	}
	std::cout << "******" << std::endl;
	//show the max Rectangle on the basis of area
	print(std::cout, find_max(vr, comparing_area< Rectangle>{}));

	std::cout << "******" << std::endl;
	//show the max Rectangle on the basis of perimeter
	print(std::cout, find_max(vr, comparing_perimeter< Rectangle>{}));
	return 1;
}	


你可能感兴趣的:(c++,笔记)