Data Structures and Algorithm Analysis in c++ 第一章筆記和部分習題

注:輸入問題懶得搞,
 A<X> 表示A的X次方
 logA(B) 表示底數爲A,真數爲B
 加減乘除等 +-*/=

 
指數 exponent
 A<X> * A<Y> = A<X + Y>
 A<X> / A<Y> = A<X - Y>
 A<X><Y> = A<X * Y>
 A<X> + A<X> = 2 * A<X> != A<2 * X>
 2<X> + 2<X> = 2 * 2<X> = 2<1 + X>
 
對數 Logarithms
 在計算機科學中,所有對數的底數默認爲2
 
 定義:
  如果有 A<X> = B,則有且僅有 logA(B) = X, 稱 X爲以 A爲底 B的對數
  
 1:
  logA(B) = logC(B) / logC(A); A,B,C > 0, A!=1
  證明:
   假設
   Z = logA(B); ==>  A<Z> = B ==> 公式3
   X = logC(A); ==>  C<X> = A ==> 公式1
   Y = logC(B); ==>  C<Y> = B ==> 公式2
   將公式1,2代入3得:
   ==> C<X><Z> = C<Y>
   ==> X * Z = Y
   ==> Y / X = Z;
   得證
   
 2:
  log(AB) = log(A) + log(B); A,B > 0
  證明:
   假設
   Z = log(AB); ==>  2<Z> = AB ==> 公式3
   X = log(A); ==>  2<X> = A ==> 公式1
   Y = log(B); ==>  2<Y> = B ==> 公式2
   將公式1,2代入3得:
   ==> 2<Z> = 2<X> * 2<Y>
   ==> Z = Y + X;
   得證
   
 3:
  log(A/B) = log(A) - log(B); A,B > 0
  證明:
   假設
   Z = log(A/B); ==>  2<Z> = A/B ==> 公式3
   X = log(A); ==>  2<X> = A ==> 公式1
   Y = log(B); ==>  2<Y> = B ==> 公式2
   將公式1,2代入3得:
   ==> 2<Z> = 2<X> / 2<Y>
   ==> Z = X - Y;
   得證
   
 4:
  log(A<B>) = B * log(A); A,B > 0
  證明:
   假設
   Z = log(A<B>); ==>  2<Z> = A<B> ==> 公式3
   X = log(A);  ==>  2<X> = A ==> 公式1
   將公式1代入3得:
   ==> 2<Z> = 2<X><B>
   ==> 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<i>的求和: 2<n + 1> - 1
   設:
    Sn = 1 + 2 + 2<2> +...+ 2<n>
   等式兩端乘以2:
    2*Sn = 2 + 2<2> + 2<3> +...+ 2<n + 1>
   兩式相減
    Sn = 2<n + 1> - 1
    
  i[0,n], A<i>的求和: (A<n + 1> - 1) / (A - 1)
   設:
    Sn = 1 + A + A<2> +...+ A<n>
   等式兩端乘以A:
    A*Sn = A + A<2> + A<3> +...+ A<n + 1>
   兩式相減
    (A - 1)Sn = A<n + 1> - 1
    Sn = (A<n + 1> - 1) / (A - 1)
   同理如果 當 0 < A < 1
    (1 - A)Sn <= 1
    Sn <= 1 / (1 - A)
    
  i[1,n], i/(2<i>)的求和: Sn <= 2
   設:
    Sn = 1/2 + 2/4 + 3/8 +...+ n/(2<n>)
   等式兩端乘以A:
    2*Sn = 1 + 2/2 + 3/4 + 3/8 +...+ n/(2<n - 1>)
   兩式相減
    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<k>的求和: 約等於 n<k + 1>/(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>
   對於i = 1,2,3, f(i) = 1,1,2, 分別小於 5/3,25/9,125/27, base case 滿足;
   假設對於 i = k, 滿足 f(k) < (5/3)<k>
   對於 i = k + 1:
    f(k + 1)  = f(k) + f(k-1)
    f(k + 1)  < (5/3)<k> + (5/3)<k-1>
    f(k + 1)  < (3/5)(5/3)<k+1> + (3/5)(3/5)(5/3)<k+1>
    f(k + 1)  < (5/3)<k+1> * (3/5 + 9/25)
    f(k + 1)  < (5/3)<k+1> * (24/25)
    f(k + 1)  < (5/3)<k+1>
   得證
  
  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<i>) 求和
  根據公式約等於 4/3
 2> i[0,n], i/(4<i>) 求和
  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<i>) 求和
  Sn = 1/4 + 4/16 + 9/64 + ...
  4*Sn = 1 + 4/4 + 9/16 + ...
  3*Sn = 1 + 3/4 + 5/16 + ... =  5 * i/(4<i>) 求和 = 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 

//==================矩形類==================

<span style="font-family:Microsoft YaHei;">#ifndef RECTANGLE_H
#define RECTANGLE_H

#include <iostream>

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	</span>


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

<span style="font-family:Microsoft YaHei;">#ifndef FINDMAX_H
#define FINDMAX_H

#include <vector>

template <typename Object, typename comparer>
const Object & find_max(const std::vector<Object> & 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</span>


//=================兩個比較面積和周長的函數對像模板===================

<span style="font-family:Microsoft YaHei;">#ifndef COMPARING_H
#define COMPARING_H

//compare area
template <typename Object>
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 <typename Object>
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</span>

//===================使用上面定義的模板類=================

<span style="font-family:Microsoft YaHei;">#include <iostream>
#include <ctime>
#include "Rectangle.h"
#include "Findmax.h"
#include "Comparing.h"

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

int main(){
	std::vector<Rectangle> 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;
}	</span>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章