610 likes | 898 Views
Lecture 2 – Dynamic array and Vector Container. 1.Dynamic array 2.Template 3.Vector(STL). lecture 2 – Dynamic array and Vector Container. lecture 2 – Dynamic array and Vector Container. 数组的特点: 1. 数据存储空间是连续的,存储的数据是相同类型的数据; 2. 数据可以通过首个数据基址+偏移量访问,即下标; 3. 数据空间是否可变更(扩大、缩小)? 4. 数据访问是否安全?
E N D
Lecture 2 – Dynamic array and Vector Container • 1.Dynamic array • 2.Template • 3.Vector(STL)
lecture 2 – Dynamic array and Vector Container
lecture 2 – Dynamic array and Vector Container 数组的特点: 1.数据存储空间是连续的,存储的数据是相同类型的数据; 2.数据可以通过首个数据基址+偏移量访问,即下标; 3.数据空间是否可变更(扩大、缩小)? 4.数据访问是否安全? 线性静态连续存储结构(数组) 线性动态连续存储结构(动态数组)
lecture 2 – Dynamic array and Vector Container C++语言支持的简单和结构化的数据类型: 1.数据存储空间自动分配; 2.数据操作方法系统给定,如[]操作; 3.用户使用时需声明变量类型,即可直接使用; 用户设计的复杂数据类型或数据结构: 1.用户自己分数据存储空间; 2.用户自己设计数据操作方法,如[]操作; 3.用户使用时需声明变量类型,即可直接使用; 数据+方法 数据+方法 ADT(抽象数据类型)
lecture 2 – Dynamic array and Vector Container Dynamic array: 1.动态申请空间 2.动态释放所申请的空间 3.数据输入(初始化) 4.数据访问(下标访问) 5.数据空间变更(扩大、缩小) 6.数据输出 Dynamic array: 1.动态申请空间 new 2.动态释放所申请的空间 delete [] 3.数据输入(初始化)construct 4.数据访问(下标访问)a[] 5.数据空间变更(扩大、缩小) new/delete 6.数据输出 /输入输出重载
lecture 2 – Dynamic array and Vector Container 如何设计Dynamic array 面向对象程序设计:类设计和实现 类:数据+方法 1.数据的空间设计 总容量:capacity 实际存放数据量:size 数据的存放空间(动态申请):指针地址 2.方法是针对这些数据的访问和操作 下标操作(包括安全检查) 尾部元素操作 数组是否为空/数据量 Capacity Size Array address 0 0 0 0 0 0 0
lecture 2 – Dynamic array and Vector Container Capacity Size Array address 1 2 3 4 5 6 7 空间扩大,原有数据需复制 1 2 3 4 5 6 7 8 1 2 3 4 5 空间缩小,原有数据需部分保留
lecture 2 – Dynamic array and Vector Container class miniVector { public: miniVector(int size = 0); miniVector(const miniVector& obj); ~miniVector(); miniVector& operator= (const miniVector& rhs); int& back(); const int& back() const; int& operator[] (int i); const int& operator[] (int i) const;
lecture 2 – Dynamic array and Vector Container void push_back(const int& item); void pop_back(); int size() const; bool empty() const; int capacity() const; private: int vCapacity; int vSize; int *vArr; void reserve(int n, bool copy); };
lecture 2 – Dynamic array and Vector Container void miniVector::reserve(int n, bool copy) { int *newArr; int i; newArr = new int[n]; if (newArr == NULL) throw memoryAllocationError( "miniVector reserve(): memory allocation failure"); if (copy) for(i = 0; i < vSize; i++)newArr[i] = vArr[i]; if (vArr != NULL)delete [] vArr; vArr = newArr; vCapacity = n; }
lecture 2 – Dynamic array and Vector Container miniVector::miniVector(int size): vSize(0), vCapacity(0), vArr(NULL) { int i; if (size == 0) return; reserve(size, false); vSize = size; for (i=0;i < vSize;i++) vArr[i] = 0; }
lecture 2 – Dynamic array and Vector Container miniVector::miniVector (const miniVector& obj): vSize(0), vCapacity(0), vArr(NULL) { int i; if (obj.vSize == 0) return; reserve(obj.vSize, false); vSize = obj.vSize; for (i = 0; i < vSize; i++) vArr[i] = obj.vArr[i]; }
lecture 2 – Dynamic array and Vector Container miniVector::~miniVector() { if (vArr != NULL) delete [] vArr; } int& miniVector::operator[] (int i) { if (i < 0 || i >= vSize) throw indexRangeError( "miniVector: index range error", i, vSize); return vArr[i]; }
lecture 2 – Dynamic array and Vector Container int& miniVector::back() { if (vSize == 0) throw underflowError( "miniVector back(): vector empty"); return vArr[vSize-1]; } void miniVector::pop_back() { if (vSize == 0) throw underflowError( "miniVector pop_back(): vector is empty"); vSize--; }
lecture 2 – Dynamic array and Vector Container void miniVector::push_back(const int& item) { if (vSize == vCapacity) { if (vCapacity == 0)reserve(1,false); else reserve(2 * vCapacity, true);//double size } vArr[vSize] = item; vSize++; } bool miniVector::empty() const { return vSize == 0; }
lecture 2 – Dynamic array and Vector Container 思考: 1.若想申请char动态数组或float动态数组,该如何修改类声明和实现? 2.若想申请用户自定义数据类型,例如time类,又该如何修改类声明和实现? 解决办法: 使用模板-解决类通用性
lecture 2 – Dynamic array and Vector Container template <typename T> //d_vector.h class miniVector { public: miniVector(int size = 0); miniVector(const miniVector<T>& obj); ~miniVector(); miniVector& operator= (const miniVector<T>& rhs); T& back(); const T& back() const; T& operator[] (int i); const T& operator[] (int i) const;
lecture 2 – Dynamic array and Vector Container void push_back(const T& item); void pop_back(); int size() const; bool empty() const; int capacity() const; private: int vCapacity; int vSize; T *vArr; void reserve(int n, bool copy); };
lecture 2 – Dynamic array and Vector Container template <typename T> void miniVector<T>::reserve(int n, bool copy) { T *newArr; int i; newArr = new T[n]; if (newArr == NULL) throw memoryAllocationError( "miniVector reserve(): memory allocation failure"); if (copy) for(i = 0; i < vSize; i++)newArr[i] = vArr[i]; if (vArr != NULL)delete [] vArr; vArr = newArr; vCapacity = n; }
lecture 2 – Dynamic array and Vector Container miniVector<T>::miniVector(int size): vSize(0), vCapacity(0), vArr(NULL) { int i; if (size == 0) return; reserve(size, false); vSize = size; for (i=0;i < vSize;i++) vArr[i] = 0; }
lecture 2 – Dynamic array and Vector Container miniVector<T>::miniVector (const miniVector& obj): vSize(0), vCapacity(0), vArr(NULL) { int i; if (obj.vSize == 0) return; reserve(obj.vSize, false); vSize = obj.vSize; for (i = 0; i < vSize; i++) vArr[i] = obj.vArr[i]; }
lecture 2 – Dynamic array and Vector Container miniVector<T>::~miniVector() { if (vArr != NULL) delete [] vArr; } T& miniVector<T>::operator[] (int i) { if (i < 0 || i >= vSize) throw indexRangeError( "miniVector: index range error", i, vSize); return vArr[i]; }
lecture 2 – Dynamic array and Vector Container T& miniVector<T>::back() { if (vSize == 0) throw underflowError( "miniVector back(): vector empty"); return vArr[vSize-1]; } void miniVector<T>::pop_back() { if (vSize == 0) throw underflowError( "miniVector pop_back(): vector is empty"); vSize--; }
lecture 2 – Dynamic array and Vector Container void miniVector<T>::push_back(const int& item) { if (vSize == vCapacity) { if (vCapacity == 0)reserve(1,false); else reserve(2 * vCapacity, true);//double size vArr[vSize] = item; vSize++; } } bool miniVector<T>::empty() const { return vSize == 0; }
lecture 2 – Dynamic array and Vector Container 声明变量: miniVector v1,v2(10),v3(5); 赋初值: v2.push_back(1); v2.push_back(2); V2.pop_back(); V2(v3); V2[0]=10; 思考:如何输出向量?
lecture 2 – Dynamic array and Vector Container 输出向量方法1 template <typename T> void writeVector(const miniVector<T>& v) { int i, n = v.size(); for(i = 0; i < n; i++) cout << v[i] << " "; cout << endl; }
lecture 2 – Dynamic array and Vector Container 输出向量方法2 template <typename T> ostream & operator<< (ostream & out, const miniVector<T> & v) { int n = v.size(); for (int i = 0; i < n; i++) out << v[i] << " "; return out; }
Vector Class : STL vector container(容器) //Template class Template <typename T> Class Vector { public: vector(); vector(int n, const T& value=T()); vector(T *first, T *last); T& back(); void push_back(); void pop_back(); T& operator[](int i); … Private: int vCapacity; //amount of available space int vSize; //number of elements in the vector T *vArr; //the dynamic array }
Construction Template <typename T> Vector<T>::Vector(int n, const T& value=T()) { T *newArr; int i; newArr=new T[n]; if(newArr==NULL) throw memoryAllocationError( “Vector Memory allocation failure”); vSize=n; vCapacity=n; for(i=0;i<vSize;i++) vArr[i]=T(); vArr=newArr; }
CLASS vector <vector> Constructors vector(); Create an empty vector. This is the default constructor. vector(int n, const T& value = T()); Create a vector with n elements, each having a specified value. If the value argument is omitted, the elements are filled with the default value for type T. Type T must have a default constructor, and the default value of type T is specified by the notation T(). 30 Main Index Contents
CLASS vector <vector> Constructors vector(T *first, T *last); Initialize the vector using the address range [first, last). The notation *first and *last is an example of pointer notation 31 Main Index Contents
CLASS vector <vector> Operations T& back(); Return the value of the item at the rear of the vector. Precondition: The vector must contain at least one element. const T& back() const; Constant version of back(). bool empty() const; Return true if the vector is empty and false otherwise. 32 Main Index Contents
CLASS vector <vector> Operations T& operator[] (int i); Allow the vector element at index i to be retrieved or modified. Precondition: The index, i, must be in the range 0 i < n, where n is the number of elements in the vector. Postcondition: If the operator appears on the left side of an assignment statement, the expression on the right side modifies the element referenced by the index. const T& operator[] (int i) const; Constant version of the index operator. 33 Main Index Contents
CLASS vector <vector> Operations void push_back(const T& value); Add a value at the rear of the vector. Postcondition: The vector has a new element at the rear and its size increases by 1. void pop_back(); Remove the item at the rear of the vector. Precondition: The vector is not empty. Postcondition: The vector has a new element at the rear or is empty. 34 Main Index Contents
CLASS vector <vector> Operations void resize((int n, const T& fill = T()); Modify the size of the vector. If the size is increased, the value fill is added to the elements on the tail of the vector. If the size is decreased, the original values at the front are retained. Postcondition: The vector has size n. int size() const; Return the number of elements in the vector. 35 Main Index Contents
lecture 2 – Dynamic array and Vector Container int intArray[5]={9,2,7,3,12} int arrSize=sizeof(intArray)/sizeof(int); Vector<int> intVector(intArray, intArray+arrSize); intVector.push_back(10); 一般文件应包含: #include<vector> #include<iostream> using namespace std;
lecture 2 – Dynamic array and Vector Container http://msdn.microsoft.com/library MSDN Library开发工具和语言 \Visual Studio 2008 \Visual Studio \Visual C++ \Visual C++ 参考 \Visual C++ Libraries Reference \STL/CLR Library vector (STL/CLR)
vector (STL/CLR) operator!= (vector) (STL/CLR) operator< (vector) (STL/CLR) operator<= (vector) (STL/CLR) operator== (vector) (STL/CLR) operator> (vector) (STL/CLR) operator>= (vector) (STL/CLR) vector::assign (STL/CLR) vector::at (STL/CLR) vector::back (STL/CLR) vector::back_item (STL/CLR) vector::begin (STL/CLR) vector::capacity (STL/CLR) vector::clear (STL/CLR) vector::const_iterator (STL/CLR) vector::const_reference (STL/CLR) vector::const_reverse_iterator (STL/CLR) vector::difference_type (STL/CLR) vector::empty (STL/CLR) vector::end (STL/CLR) vector::erase (STL/CLR) vector::front (STL/CLR) vector::front_item (STL/CLR) vector::generic_container (STL/CLR) vector::generic_iterator (STL/CLR) vector::generic_reverse_iterator (STL/CLR) vector::generic_value (STL/CLR) vector::insert (STL/CLR) vector::iterator (STL/CLR) vector::operator= (STL/CLR) vector::operator[] (STL/CLR) vector::pop_back (STL/CLR) vector::push_back (STL/CLR) vector::rbegin (STL/CLR) vector::reference (STL/CLR) vector::rend (STL/CLR) vector::reserve (STL/CLR) vector::resize (STL/CLR) vector::reverse_iterator (STL/CLR) vector::size (STL/CLR) vector::size_type (STL/CLR) vector::swap (STL/CLR) vector::to_array (STL/CLR) vector::value_type (STL/CLR) vector::vector (STL/CLR)
lecture 2 – Dynamic array and Vector Container String类-Standard C++ Library Char str[]=‘A string’; Str字符串长度是8。 字符数组不是C语言风格的字符串,除非结尾加入NULL Char arr[10]; arr[0]=‘C’;arr[1]=‘+’;arr[2]=‘+’;arr[3]=0;
lecture 2 – Dynamic array and Vector Container String 在C++程序设计环境里,许多类的声明都包括C语言风格的字符串,如文件流的open()函数,需要使用C语言风格的字符串来标识文件。 Ifstream fin; fin.open(<C-style string>) 例如: string filename=“input.dat”; fin.open(filename.c_str()); 参考:http://wenku.baidu.com/view/a1a727fb770bf78a65295486.html
lecture 2 – Dynamic array and Vector Container String类-Standard C++ Library Members: (字符串比较大小) operator+ operator!= operator== operator< operator<= operator<< operator> operator>= operator>>
lecture 2 – Dynamic array and Vector Container String类-Standard C++ Library Function: getline( _Istr(输入流), _Str(读入后的字符串), ( ‘\n’ )(结束符) ). 例如: 输入:Jdoe:vswerfa string username,userpwd; ifstream fin; getline(fin,usename,’:’); getline(fin,usepwd,’/n’);
lecture 2 – Dynamic array and Vector Container basic_string Members append :追加 assign :赋值 at :返回特定位置的元素引用 c_str :Converts the contents of a string as a C-style compare copy erase find find_first_of find_last_of insert push_back replace reserve resize size substr swap ……
lecture 2 – Dynamic array and Vector Container C风格字符串 #include<string.h> char a[4]=“abc”,b[5]=“kxyz”; For(int i=0;a[i]!=‘\0’;i++) cout<<a[i]; strcat(a,b); strcpy(a,b); strcmp(a,b); strlen(a); String类 #include<string> string s1(“abc”),s2(5,’d’),s3(s1,2); string s4,s5; cout<<s1.size(); cin>>s4; getline(cin,s5); S1.append(s2); S1.insert(1,s3,2); S1.replace(2,3,s4); S1.swap(s5); S1.find_first_of(s2,2);
lecture 2 – Dynamic array and Vector Container 模式匹配 1、简单模式匹配算法 O(m*n)(BF, Brute Force) 正文:a b a b c a b c a a b c b (n) 字串:a b a b b (m) 匹配过程: i=1 a b a b c a b c a a b c b a b a b b i=2 a b a b c a b c a a b c b a b a bb i=3 a b a b c a b c a a b c b a b a bb ……. 时间复杂度O(m*n)
lecture 2 – Dynamic array and Vector Container 2、Knuth-Morris-Pratt(KMP)模式匹配算法 O(m+n) (基于Cook提出理论,任何一个可以使用被称为下推自动机的计算机抽象模型来解决的问题,也可以使用一个实际的计算机在与问题规模对应的时间内解决,这个理论暗示模式匹配算法理论上可以达到O(m+n)) 正文:a b a b c a b c a a b c b a a b a a b c 子串:a b a b c a b a b a b c 匹配过程: i=8 a b a b c a b c a a b c b a a b a a b c a b a b c a b a b a b c j=8
lecture 2 – Dynamic array and Vector Container 2、Knuth-Morris-Pratt(KMP)模式匹配算法 i=8 a b a b c a bc a a b c b a a b a a b c a b a b c a b a b a b c j=8 注意模式串移动,因为模式串开始连续6位的子串ababca和冲突点a前面的子串babcab不等,所以模式串先前移动1位是不会跟主串粉色的babcab相等的: a b a b c a bc a a b c b a a b a a b c a b a b c a b a b a b c a b a b c a b a b a b c
lecture 2 – Dynamic array and Vector Container 2、Knuth-Morris-Pratt(KMP)模式匹配算法 同理:因为模式串开始连续5位的子串ababc和冲突点a前面的子串abcab不等,所以模式串先前移动2位也不会跟主串粉色的abcab相等的: a b a b c a bc a a b c b a a b a a b c a ba b c a b a b a b c a b a b cab a b a b c 继续,连续4位的子串也不等,也就不会跟主串等: a ba b c a bc a a b c b a a b a a b c a ba b c a b a b a b c a b a b c ab a b a b c
lecture 2 – Dynamic array and Vector Container 2、Knuth-Morris-Pratt(KMP)模式匹配算法 之后,连续3位的子串也不等,也就不会跟主串等: a ba b c a bc a a b c b a a b a a b c a bab c a b a b a b c a b a bc ab a b a b c 之后,连续2位的子串和冲突点a前面的子串ab相等,即跟主串ab相等,但既然相等,这两个子串也不需要比较,只需比较子串的第3位跟主串的第8位是否相等即可,这样主串的下标i就不用先前移动,即不向前回溯,保证i一直向后走,不回头: a ba bc a bc a a b c b a a b a a b c a bab c a b a b a b c a b a bc ab a b a b c
lecture 2 – Dynamic array and Vector Container 所以,关键是分析模式串的重复规律,计算方法如下: 子串: a b a b c a b a b a b c 对字串计算下一次比较位的next[ ]值(前缀数组): next[ ] 0 1 1 2 3 1 2 3 4 5 4 5 a b a b c a b a b a b c (计算b之前与子串从头开始最长的匹配字符长度,0,则加1,为1) a ba b c a b a b a b c a b a b c a b a b a b c (计算a之前与子串从头开始最长的匹配字符长度,不匹配,则0加1,为1) a b ab c a b a b a b c a b a b c a b a b a b c (计算b之前与子串从头开始最长的匹配字符长度,1,则加1为2)