编程原本(4~6)读书笔记

第四章 线性序

本章讨论了二元关系的性质比如传递性和对称性,着重介绍了全序和弱线性序,给数据的有序存储打下基础。

Relation(Op)=

      HomogeneousPredicate(Op)

    ^Arity(Op) = 2    // 关系的定义:两元同源谓词

Property(R:Relation)   // 传递性的定义

transitive:R

     r->(r(a,b)^r(b,c) => r(a,c))


严格的(strict):关系对其自身之间的作用无效。比如大于,对自己和自己比较是没有意义的。

自反的(reflexive): 关系对其自身之间总有这一关系。

对称的(symmetric):如果关系在一个方向成立在另一方向也成立,比如A是B的兄弟,同样B也是A的兄弟。

反对称(asymmetric):在一个方向成立绝对不在另一个方向成立,比如A是B的父亲,那B绝对不是A的父亲。


equivalence:R   // 相等的完整定义: 具有传递  自反  对称这三种特性的一种关系

    r-> transitive(r) ^ reflexive(r) ^ symmetric (r)


三分律(tri-chotomy law):两个数之间的关系不是大于就是小于或者等于。

排序算法的稳定性:当两个元素相等时,比较的结果不会破坏其原来的顺序,举例来讲如果  a=b,那么排序的结果不会让b跑到a前面。


第五章  有序代数结构

单位元: 它和任意其他元素组合总得到那个元素,比如乘法的1,加法的0

半群(semigroup):带有一个可交换的运算的集合。比如加法可交换那就是加半群,某些乘法就不是半群,比如矩阵相乘。

幺半群(monoid): 带有单位元的半群。  那带有0的加法,那就是加法幺半群。带有1的乘法就是乘法幺半群。

群(group):带有逆运算的幺半群。

半环:当一个类型同时有加法和乘法。


求余

作者写了一个递归形式的算法,还介绍了Floyd and Knuth的算法,我更倾向后面这种,

template<typename T>
    requires(HalvableMonid(T))
T remainder_nonnegative_iterative(T a, T b)
{
    if(a<b) return a;
    T c=largest_double(a, b);
    a =a-c;
    while(c!=b){
        c=half(c);
        if(c<=a) a=a-c;
    }
    return a;
}

template<typename T>
    requires(ArchimedeanMonoid(T))
T largest_doubling(T a, T b){
    while(b<a-b) b= b+b;
    return b;
}

最大公因子

gcd(a, b) = gcd(a-b, b)

先根据上门的公式实现一种简单的算法

template<typename T>
T substarctive_gcd_nozero(T a, T b){
    while(true){
        if(b<a)    a=a-b;
        else if(a<b)  b=b-a;
        else return a;
    }
} 
利用上面求余的快速算法,加上对特殊情况0的处理得到下面优化算法

template<typename T>
T fast_subtractive_gcd(T a, T b){
      while(true){
          if(b==T(0))  return a;
         a = remainder_nonnegative_iterative(a, b);
         if(a==T(0))  return b;
         b=remainder_nonnegative_iterative(b,a);
     }
}

template<typename T>
pair<QuotientType(T), T>
quotient_remainder_nonegative_iterative(T a, T b){
    typedef QuotientType(T) N;
    if(a<b) return pair<N,T>(N(0), a);
    T c = largest_doubling(a, b);
    a=a-c;
    N n(1);
    while(c!=b){
         n=twice(n);
	c=half(c);
	if(c<=a){
		a=a-c;
		n=successor(n);    // ++n
	}
    }
	return pair<N, T>(n,a);
}

第六章   迭代器

迭代器就是stl的灵魂之一,本章从数学的角度对不同的迭代器进行了规范,由于使用stl时候已经感觉到迭代器的好处,所以就不再详细阅读。






你可能感兴趣的:(编程原本(4~6)读书笔记)