diff --git a/thu_dsa/chp2/Vector.h b/thu_dsa/chp2/Vector.h index 2ef7ba0..11f2f7b 100644 --- a/thu_dsa/chp2/Vector.h +++ b/thu_dsa/chp2/Vector.h @@ -13,7 +13,7 @@ using std::endl; template class Vector{ protected: - T* _elem; + T* _elem; int _size; int _capacity; @@ -39,6 +39,10 @@ public: void print(void); int find(T const &elem); int find(T const &elem, int lo, int hi); + int search(T const &elem, int lo, int hi); + int fib_search(T const &elem, int lo, int hi); + int binary_search(T const &elem, int lo, int hi); + int interpolation_search(T const &elem, int lo, int hi); int getSize() { return _size; } int getCapacity() { return _capacity; } bool empty(){ return _size == 0;} @@ -55,6 +59,7 @@ public: T pop(int lo, int hi);//return the last element popped int remove(T const &elem);//remove first element matched, return index, -1 if not found int unique(void); //return the number of elements deleted + int uniquify(void);//unique method for sorted vector void map(void(*visit)(T&)); template void map(VST& visit); }; @@ -117,6 +122,28 @@ int Vector::find(T const &elem, int lo, int hi){ return pos; } +template +int Vector::search(T const &elem, int lo, int hi){ + int mid; + while (lo < hi) { + mid = (lo + hi) >> 1; + if (elem < _elem[mid]) hi = mid; + else if (_elem[mid] < elem) lo = mid + 1; + else return mid; + } + return lo - 1; +} + +template +int Vector::binary_search(T const &elem, int lo, int hi){ + int mid; + while(lo < hi){ + mid = (lo + hi) >> 1; + elem < _elem[mid] ? hi = mid : lo = mid + 1; + } + return lo - 1; +} + // writable interfaces template @@ -181,6 +208,15 @@ int Vector::unique(){ return count; } +template +int Vector::uniquify(){ + int i = 0, j = 0; + while (++j != _size) + if (_elem[i] != _elem[j]) _elem[++i] = _elem[j]; + _size = i + 1; + return j - i - 1; +} + template void Vector::map(void(*visit)(T&)){ for (int ix = 0; ix != _size; ++ix) visit(_elem[ix]); diff --git a/thu_dsa/chp2/testVector.cpp b/thu_dsa/chp2/testVector.cpp index a98d5fb..1cef1f0 100644 --- a/thu_dsa/chp2/testVector.cpp +++ b/thu_dsa/chp2/testVector.cpp @@ -11,6 +11,7 @@ void test_insert(); void test_delete(); void test_find(); void test_unique(); +void test_search(); void test_map(); int main(){ @@ -20,6 +21,7 @@ int main(){ test_delete(); test_find(); test_unique(); + test_search(); test_map(); system("pause"); @@ -137,6 +139,41 @@ void test_unique(){ assert(v.getSize() == 10); assert(v[9] == 5); + // test basic function + int B[] = { 1,1,1,2,2,3,3,3,3,3,4,4,5,6,6,7,7,7,8,8,9,9,9,9,9,9 }; + v = Vector(B, 26); + assert(v.uniquify() == 17); + assert(v.getSize() == 9); + for (int ix = 0; ix != 9; ++ix) + assert(v[ix] == ix + 1); + + //test running time + //remain to be done + + cout << "test passed." << endl; +} + +void test_search(){ + cout << "run test_search..."; + int A[] = { 2,5,6,8,9,10,13,14,17,19,21,22,30,32 }; + Vector v(A, 14); + + //test search + assert(v.search(14, 0, v.getSize()) == 7); + assert(v.search(14, 9, v.getSize()) == 8); + assert(v.search(1, 0, v.getSize()) == -1); + + //test binary_search + assert(v.binary_search(14, 0, v.getSize()) == 7); + assert(v.binary_search(15, 0, v.getSize()) == 7); + assert(v.binary_search(14, 9, v.getSize()) == 8); + + int B[] = { 1,1,1,2,2,3,3,3,3,3,4,4,5,6,6,7,7,7,8,8,9,9,9,9,9,9 }; + v = Vector(B, 0, 26); + assert(v.binary_search(3, 0, v.getSize()) == 9); + assert(v.binary_search(9, 0, v.getSize()) == 25); + assert(v.binary_search(0, 0, v.getSize()) == -1); + cout << "test passed." << endl; } diff --git a/thu_os/chp1.md b/thu_os/chp1.md index 761b640..b7dd5bd 100644 --- a/thu_os/chp1.md +++ b/thu_os/chp1.md @@ -19,7 +19,7 @@ BIOS -> 加载程序(Bootloader) -> 操作系统 简单的过程就是上面那样,但是这里需要明确一些问题。 -首先,为什么需要Bootloader这样一个程序,为什么不能直接由BIOS读入操作系统? +> 首先,为什么需要Bootloader这样一个程序,为什么不能直接由BIOS读入操作系统? + 这是因为操作系统的种类复杂,有许多不同的操作系统,他们各自具有不同的文件系统。BIOS的内容是出厂固化的,不可能使之可以分辨所有的操作系统。让BIOS的那点程序分辨不同操作系统的文件系统,并将其加载到内存中,会使BIOS的设计非常复杂,以至于BIOS自己就成为了一个操作系统。 @@ -80,13 +80,13 @@ BIOS -> 磁盘主引导扇区的主引导记录 -> 活动分区的引导扇区 ## 中断,异常,系统调用 -还是一个问题,为什么操作系统需要中断、异常和系统调用? +> 还是一个问题,为什么操作系统需要中断、异常和系统调用? 其实,按照软件工程的思想,这三者都是操作系统对外提供的接口,外部的应用程序可以通过这三种接口进入操作系统内核,而不能直接操作底层的寄存器这种,都是为了操作更加地安全。 这是因为,在计算机运行当中,只有内核才是被信任的第三方,只有内核才能执行特权指令。这就好比你去银行取钱,你可以通过柜台或者是自动取款机取钱,却不可以直接去保险柜里面拿钱。 -接下来辨析一下中断,异常和系统调用的区别 +> 接下来辨析一下中断,异常和系统调用的区别 + 中断是用于服务硬件的,是处理来自硬件设备的处理请求,如键盘中断这种。 + 异常是用于处理非法指令或者其他原因导致当前指令执行失败,例如除零异常,缺页异常这种