Ⅶ 类模板与STL编程 ①
Posted syzyaa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ⅶ 类模板与STL编程 ①相关的知识,希望对你有一定的参考价值。
1.类模板的概念
1.1 函数模板的回顾
template <class T1, class T2> T1 add(T1 x, T2 y) { return x+y; } int main() { cout << add(9, ‘A’) << endl; //两种表达形式 cout << add<int, char>(9, ‘A’) << endl; }
1.2 类模板的定义
template <class T, int size> //class:参数化类型 int:普通类型 class CSafeArray //既然上面出现了class,接下来就要对class进行定义 { T a[size]; public: CSafeArray() //初始化 { for(int i=0; i<size; i++) a[i] = i; } T &operator[](int i) //函数模板:类模板中的成员函数 { if(i<0 || i>size-1) { cout << "Index value of " << i << " is out-of-bounds. "; exit(1); } return a[i]; } };
//在类外面定义 template <class T, int size> class CSafeArray { T a[size]; public: CSafeArray() { for(int i=0; i<size; i++) a[i] = i; } T &operator[](int i); }; template <class T, int size> //写在外面的话就要把这个头加上 T &CSafeArray<T, size>::operator[](int i) //再加上作用域 { if(i<0 || i>size-1) { cout << "Index value of "; cout << i << " is out-of-bounds. "; exit(1); } return a[i]; }
1.3 类模板的实例化
和函数的实参与形参结合类似
const int SIZE = 10; CSafeArray<int, SIZE> intOb; //带入即可 cout << "Integer array: "; for(int i=0; i<SIZE; i++) intOb[i] = i; //其实是个操作符 for(int i=0; i<SIZE; i++) cout << intOb[i] << " "; cout << ‘ ‘;
1.4 带默认参数的类模板
与带默认形参的函数类似
template <class T=int, int size=10> //一开始有了默认的 class CSafeArray{}; //使用的时候可以啥也不写 CSafeArray <>intOb;
2.类模板的应用
2.1 顺序堆栈类模板(先进后出)
const int SIZE = 10; template <class ST> class stack { ST s[SIZE]; int top; public: stack() { top = 0; } void Push(ST ob); ST Pop(); }; // Push an object. template <class ST> //在外面的话,每个都要加 void stack<ST>::Push(ST ob) { if(top==SIZE) { cout << "Stack is full. "; return; } s[top] = ob; top++; } int main() { int i; stack<char> cs; cs.Push(‘a‘); cs.Push(‘b‘); cs.Push(‘c‘); for(i=0; i<3; i++) cout << "Pop s1: " << cs.Pop() << " "; }
2.2 顺序队列类模板(先进先出)
2.3 链表类模板
template <class ElemType> struct LNode { ElemType data; LNode *next; LNode(ElemType _data=0, LNode *_next=NULL) { data = _data; next = _next; } }; template <class ElemType> class LinkList { LNode<ElemType> *head; LNode<ElemType> * rear; int size; public: LinkList(ElemType *data=NULL, int n=0); ~LinkList(); void Clear(); bool IsEmpty(); int GetLength(); … void Print(); };
3.STL编程
3.1 STL简介
? 时间复杂度
3.2 STL容器
3.2.1 定义
一个通用的数据结构,可以处理不同的数据类型
3.2.2 容器
① 顺序容器(sequence)
? 特点:来一个进一个,与值无关,不会自动排序
? 向量容器(vector)
# 栗子
#include <vector> int main() { vector<int> v; //或者v(6,1),即一共六个元素,初始化为1 for (int i=0; i<6; ++i) v.push_back(i); //或者v[i]=i; for (int i=0; i<3; ++i) v.pop_back(); for (int i=0; i<v.size(); ++i) cout << v[i] << ‘ ‘; cout << endl; }
# 复杂度:随机存取+在末尾插入和删除:O(1)
# 适用范围:快速存取&不频繁的插入删除的场合
? 列表容器(list)
# 栗子??
#include <list> #include <vector> #include <iostream> using namespace std; int main () { list<int> ml; list<int>::iterator it; for (int i=1; i<=5; i++) ml.push_back(i); //1,2,3,4,5 it = ml.begin(); ++it; ml.insert (it,10); //在所指定元素之前 //1,10,2,3,4,5 ml.insert (it,2,20);//it仍然指的是2 //1,10,20,20,2,3,4,5 --it; //指向第二个20 vector<int> mv (2,30); //30,30 ml.insert (it,mv.begin(),mv.end()); //1,10,20,30,30,20,2,3,4,5 for (it=ml.begin(); it!=ml.end(); it++) cout << " " << *it; cout << endl; }
# 迭代器
## 定义:特殊的指针,在顺序容器或关联容器中,能对每个元素进行连续存取的对象
## 格式: 容器名<数据类型>::iterator 迭代器名
## 作用:提供一种一般化的方法,对不同类型容器中的元素进行访问
## 非标准迭代器
const_iterator
reverse_iterator
const_reverse_iterator
# 还有一个栗子
#include <list> #include <vector> #include <iostream> using namespace std; int main () { list<int> first, second; first.push_back (1); first.push_back (2); first.push_back (9); second.push_back (3); second.push_back (7); second.push_back (4); first.sort(); second.sort(); first.merge(second); //把二倒入一里,二空了,一里面的顺序是升序 second.push_back (5); first.merge(second); //it就是指针嘛 for (list<int>::iterator it=first.begin(); it!=first.end(); ++it) cout << *it << " "; cout << endl; }
? 双端队列容器(deque)
# 栗子
#include <deque> #include <string> #include <iostream> using namespace std; int main() { deque<string> ds; ds.assign (3,string("Hello")); //三个hello ds.push_back ("] last"); //在头部增加一个元素 ds.push_front ("first ["); //在尾部增加一个元素 for (int i=0; i<ds.size(); ++i) cout << ds[i] << " "; cout << endl; ds.pop_front(); //删除第一个元素 ds.pop_back(); //删除最后一个个元素 for (int i=1; i<ds.size(); ++i) ds[i] = "another " + ds[i]; //在前面加hello ds.resize (4, "Hello C++"); //更改容器大小,改为四,在最后加C++一句 for (int i=0; i<ds.size(); ++i) cout << ds[i] << " "; cout << endl; }
输出:first [ Hello Hello Hello ] last
Hello another Hello another Hello Hello C++
② 关联容器(sorted associative)
? 特点:元素的添加或插入与元素的值相关
? 集合(set)
#include <set> int main () { set<int> myset; set<int>::iterator it; pair<set<int>::iterator,bool> ret; for (int i=1; i<=5; i++) myset.insert(i*10); ret = myset.insert(20); if (ret.second==false) it=ret.first; myset.insert (it,25); myset.insert (it,24); myset.insert (it,26); int myints[]= {5,10,15}; myset.insert (myints,myints+3); for (it=myset.begin(); it!=myset.end(); it++) cout << " " << *it; cout << endl; }
? 映射(map)
#include <map> int main() { map<char, int> m; //一对 map<char, int>::iterator p; int i; char ch; for(i=0; i<26; i++) m.insert(pair<char, int>(‘A‘+i, 65+i)); cout << "Enter key: "; cin >> ch; p = m.find(ch); if(p != m.end()) cout << "Its ASCII value is " << p->second; else cout << "Key not in map. "; }
? 多映射(multimap) (允许有重复的元素)
#include <map> int main() { multimap<string,string> dict; multimap<string,string>::iterator p; dict.insert(make_pair("smart","聪明的")); dict.insert(make_pair("smart","漂亮的")); dict.insert(make_pair("smart","巧妙的")); dict.insert(make_pair("smart","敏捷的")); dict.insert(make_pair("wise","聪明的")); dict.insert(make_pair("clever","聪明的")); for (p = dict.begin(); p != dict.end(); ++p) cout << p->first.c_str() << " "<< p->second << endl; string word("smart"); for (p = dict.lower_bound(word); p != dict.upper_bound(word); ++p) cout << " " << p->second << endl; word = ("聪明的"); for (p = dict.begin(); p != dict.end(); ++p) if (p->second == word) { cout << " " << p->first << endl; } }
③ 容器适配器(adaptors)
? 由顺序容器转换出的新容器:list→queue;vector→stack
? 队列 queue
#include <queue> int main () { queue<int> myqueue; int myint; cout << "Please enter some integers (enter 0 to end): "; do { cin >> myint; myqueue.push (myint); //入列 } while (myint); while (!myqueue.empty()) { cout << myqueue.front() << " "; //出列 myqueue.pop(); //去顶 } }
#include <queue> int main() { priority_queue<float> q; q.push(66.6); q.push(22.2); q.push(44.4); cout << q.top() << ‘ ‘; q.pop(); cout << q.top() << endl; q.pop(); q.push(11.1); q.push(55.5); q.push(33.3); q.pop(); while (!q.empty()) { cout << q.top() << ‘ ‘; //不是push了 q.pop(); } cout << endl; }
? 堆栈 stack
#include <stack> int main() { stack<int> st; st.push(1); st.push(2); st.push(3); cout << st.top() << ‘ ‘; st.pop() ; cout << st.top() << ‘ ‘; st.pop() ; st.top() = 77; st.push(4); st.push(5); st.pop() ; while (!st.empty()) { cout << st.top() << ‘ ‘; st.pop() ; } cout << endl; }
? 特殊容器(special)
# 位集bitset
## 灵活对二进制位进行操作
## 整型到二进制的转换
## 位的直接访问和设置
#include <bitset> #include <limits> #include <iostream> using namespace std; int main() { cout << "267 as binary short: " << bitset<numeric_limits<unsigned short>::digits>(267) << endl; cout << "267 as binary long: " << bitset<numeric_limits<unsigned long>::digits>(267) << endl; cout << "10,000,000 with 24 bits: " << bitset<24>(1e7)<< endl; }
267 as binary short: 0000000100001011
267 as binary long: 00000000000000000000000100001011
10,000,000 with 24 bits: 100110001001011010000000
#include <bitset> #include <limits> #include <iostream> using namespace std; int main() { bitset<16>flags(0xFFF0); flags[2] = true; flags[3] = flags[2]; flags[2].flip(); if (flags[13]) flags [0] = ~flags [2]; cout << flags << endl; }
1111111111111001
以上是关于Ⅶ 类模板与STL编程 ①的主要内容,如果未能解决你的问题,请参考以下文章