6.6-数据结构&算法-列表/堆栈/队列
五、列表
4.merge - 合并
void merge (list& lst);
void merge (list& lst, Comp compfunction);
将有序的参数列表合并到调用列表中,保证合并后的调用列表依然有序。
注意:任何容器,在结构性修改之前获得的迭代器,有可能因为这种修改而失效,或者不能标识正确的位置,需要重新初始化。
六、堆栈
stack 底层容器vector/deque/list
push push_back
pop pop_back
top back
size size
empty empty
... ...
#include <stack>
stack<int, vector<int> > si;
stack<string, list<string> > ss;
stack<double> sd; // 缺省底层容器deque
template<typename T, typename C>
stack {
public:
void push (const T& data) {
m_container.push_back (data);
}
void pop (void) {
m_conainer.pop_back ();
}
T& top (void) {
return m_container.back ();
}
private:
C m_container;
};
七、队列
queue 底层容器deque/list
push push_back
pop pop_front
front front
back back
size size
empty empty
...
queue<int, list<int> > qi;
queue<string> qs; // 缺省底层容器deque
八、优先队列(priority_queue)
优者先出
底层容器:vector/deque/list,缺省deque
通过类型实参以比较器的形式定义比较规则
九、映射(map)
1.key-value对的容器,通过pair表示key-value对。
template<typename FIRST, typename SECOND>
class pair {
prublic:
...
FIRST first;
SECOND second;
};
2.key唯一且升序。
3.支持下标运算符,可以用[key]访问value。
4.可以通过比较器类型自定义key升序的规则。
练习:编写程序,统计一个文本文件中每个单词出现的频率。按照词汇表的顺序打印输出。
apple : 2
beijing : 2
c++ : 3
...
十、集合
十一、多重映射
key可重复,升序,迭代时key相同的元素相邻。
upper_bound(key)成员函数返回和参数key相匹配的所有记录中最后一条记录的下一条记录的迭代器。
十二、多重集合
十三、泛型算法
1.STL中包含60种泛型算法,其中包含23种非修改算法,如find,37种修改算法,如sort。
2.STL中的泛型算法多数都会迭代器实现对容器元素的访问。
3.STL中的泛型算法凡是涉及到比较大小的算法,都支持两种比较方案——“<”运算符和比较器函数对象。
4.除了STL中的容器以外,程序员也可以使自定义的容器,获得STL泛型算法的支持,只要改自定义类型能够支持此算法对迭代器的使用规则即可。
练习:实现一个泛型的拷贝函数,用将一个容器中数据拷贝到另一个容器中。
POP->OOP->DP
copy.cpp
#include <vector> #include <deque> #include <list> #include "../day12/print.h" template<typename IT1, typename IT2> void my_copy (IT1 begin, IT1 end, IT2 to) { while (begin != end) *(to++) = *(begin++); } int main (void) { int arr1[5] = {10, 20, 30, 40, 50}; int arr2[5]; copy (arr1, arr1 + 5, arr2); print (arr2, arr2 + 5); vector<int> vec (5); copy (arr1, arr1 + 5, vec.begin ()); print (vec.begin (), vec.end ()); deque<int> deq (5); copy (vec.begin (), vec.end (), deq.begin ()); print (deq.begin (), deq.end ()); list<int> lst (5); copy (deq.begin (), deq.end (), lst.begin ()); print (lst.begin (), lst.end ()); return 0; }
list.cpp
#include <list> #include "../day12/print.h" int main (void) { int ai1[] = {13, 45, 67, 88, 92, 107}; int ai2[] = {22, 23, 37, 50, 69, 100, 109}; list<int> li1 (ai1, ai1 + 6); list<int> li2 (ai2, ai2 + 7); print (li1.begin (), li1.end ()); print (li2.begin (), li2.end ()); li1.merge (li2); print (li1.begin (), li1.end ()); print (li2.begin (), li2.end ()); list<int>::iterator it = li1.begin (); li1.insert (it, 1000); it = li1.begin (); li1.insert (it, 2000); print (li1.begin (), li1.end ()); return 0; }
map.cpp
#include <iostream> #include <map> using namespace std; class Candidate { public: Candidate (const char* name = "") : m_name (name), m_votes (0) {} const string& name (void) const { return m_name; } size_t votes (void) const { return m_votes; } void vote (void) { ++m_votes; } private: string m_name; size_t m_votes; }; int main (void) { map<char, Candidate> mc; mc.insert (make_pair ('B', "赵云")); mc.insert (pair<char, Candidate> ('A', "张飞")); mc['D'] = "刘备"; mc['E'] = "曹操"; mc['C'] = "关羽"; mc['D'] = "黄忠"; mc.insert (pair<char, Candidate> ('A', "马超")); typedef map<char, Candidate>::iterator IT; typedef map<char, Candidate>::const_iterator CIT; for (size_t i = 0; i < 10; ++i) { for (CIT it=mc.begin (); it != mc.end (); ++it) cout << '(' << it->first << ')' << it->second.name () << ' '; cout << endl << "请投下宝贵的一票:" << flush; char key; cin >> key; IT it = mc.find (key); if (it == mc.end ()) { cout << "此票作废!" << endl; continue; } it->second.vote (); } CIT win = mc.begin (); for (CIT it = mc.begin (); it != mc.end (); ++it){ cout << it->second.name () << "获得" << it->second.votes () << "票。" << endl; if (it->second.votes () > win->second.votes ()) win = it; } cout << "恭喜" << win->second.name () << "同学当选" "为首席保洁员!" << endl; return 0; }
map2.cpp
#include <iostream> #include <fstream> #include <map> #include <cstring> using namespace std; class CmpStr { public: bool operator() (const string& a, const string& b) const { return strcasecmp (a.c_str (), b.c_str ()) < 0; } }; class A { public: A (int i) : m_i (i) {} bool operator< (const A& a) const { return m_i < a.m_i; } int m_i; }; int main (int argc, char* argv[]) { if (argc < 2) { cerr << "用法:" << argv[0] << " <文件>"<<endl; return -1; } ifstream ifs (argv[1]); if (! ifs) { perror ("打开文件失败"); return -1; } map<string, int, CmpStr> msi; string word; while (ifs >> word) ++msi[word]; ifs.close (); for (map<string, int>::iterator it = msi.begin (); it != msi.end (); ++it) cout << it->first << " : " << it->second<<endl; map<A, int> mai; mai[A (100)] = 1000; mai[A (500)] = 5000; mai[A (300)] = 3000; mai[A (400)] = 4000; mai[A (200)] = 2000; map<A, int>::iterator it = mai.find (A (400)); cout << it->second << endl; return 0; }
mmap.cpp
#include <iostream> #include <map> using namespace std; int main (void) { multimap<string, int> msi; msi.insert (make_pair ("张飞", 100000)); msi.insert (make_pair ("赵云", 200000)); msi.insert (make_pair ("张飞", 300000)); msi.insert (make_pair ("关羽", 400000)); msi.insert (make_pair ("赵云", 500000)); msi.insert (make_pair ("关羽", 600000)); typedef multimap<string, int>::const_iterator CIT; for (CIT it = msi.begin (); it != msi.end ();++it) cout << it->first << " : " << it->second<<endl; cout << "-------------" << endl; for (CIT it = msi.begin (); it != msi.end();++it){ string key = it->first; CIT end = msi.upper_bound (key); int sum = 0; for (; it != end; ++it) sum += it->second; cout << key << " : " << sum << endl; --it; } return 0; }
mset.cpp
#include <iostream> #include <set> using namespace std; int main (void) { const char* candidates[] = { "张飞", "赵云", "关羽", "刘备", "曹操", NULL}; multiset<string> ms; for (size_t i = 0; i < 10; ++i) { for (size_t i = 0; candidates[i]; ++i) cout << '(' << char ('A' + i) << ')' << candidates[i] << ' '; cout << endl << "请投下您庄严的一票:" <<flush; char key; cin >> key; if (key < 'A' || 'E' < key) { cout << "此票作废!" << endl; continue; } ms.insert (candidates[key-'A']); } multiset<string>::iterator win = ms.begin (); for (multiset<string>::iterator it = ms.begin (); it != ms.end (); ++it) { cout << *it << "获得" << ms.count (*it) << "票。" << endl; if (ms.count (*it) > ms.count (*win)) win = it; it = ms.upper_bound (*it); --it; } cout << "热烈祝贺" << *win << "当选垃圾长!" << endl; return 0; }
oop.cpp
#include <iostream> using namespace std; class Calculator { public: Calculator (char op) : m_op (op) {} double calculate (double x, double y) { switch (m_op) { case '+': return x + y; case '-': return x - y; case '*': return x * y; case '/': return x / y; default: throw "无效运算符号!"; } } private: char m_op; }; int main (void) { cout << "左操作数:" << flush; double x; cin >> x; cout << "右操作数:" << flush; double y; cin >> y; cout << "运算符号:" << flush; char op; cin >> op; cout << "运算结果:" << Calculator (op).calculate ( x, y) << endl; return 0; }
pop.cpp
#include <iostream> using namespace std; int main (void) { cout << "左操作数:" << flush; double x; cin >> x; cout << "右操作数:" << flush; double y; cin >> y; cout << "运算符号:" << flush; char op; cin >> op; double z; switch (op) { case '+': z = x + y; break; case '-': z = x - y; break; case '*': z = x * y; break; case '/': z = x / y; break; default: cout << "无效运算符号!" << endl; return -1; } cout << "运算结果:" << z << endl; return 0; }
pqueue.cpp
#include <iostream> #include <queue> using namespace std; class Student { public: Student (const string& name, float score) : m_name (name), m_score (score) {} void print (void) const { cout << m_name << "," << m_score << endl; } bool operator< (const Student& student) const { return m_score > student.m_score; } private: string m_name; float m_score; }; class CmpInt { public: bool operator() (int a, int b) { return a > b; } }; int main (void) { // priority_queue<int> pqi; priority_queue<int, deque<int>, CmpInt> pqi; pqi.push (23); pqi.push (12); pqi.push (23); pqi.push (27); pqi.push (19); while (! pqi.empty ()) { cout << pqi.top () << ' '; pqi.pop (); } cout << endl; priority_queue<Student> pqs; pqs.push (Student ("张飞", 65)); pqs.push (Student ("关羽", 60)); pqs.push (Student ("赵云", 85)); pqs.push (Student ("刘备", 95)); pqs.push (Student ("曹操", 25)); while (! pqs.empty ()) { pqs.top ().print (); pqs.pop (); } return 0; }
queue.cpp
#include <iostream> #include <queue> #include <list> using namespace std; int main (void) { queue<string, list<string> > qs; qs.push ("我"); qs.push ("要"); qs.push ("吃"); qs.push ("饭"); while (! qs.empty ()) { cout << qs.front (); qs.pop (); } cout << endl; return 0; }
set.cpp
#include <iostream> #include <set> #include <fstream> using namespace std; int main (void) { ifstream ifs ("test.txt"); set<string> ss; string word; while (ifs >> word) ss.insert (word); ifs.close (); for (set<string>::iterator it = ss.begin (); it != ss.end (); ++it) cout << *it << endl; cout << "共" << ss.size () << "个不同单词。" << endl; return 0; }
sort.cpp
#include <vector> #include <list> #include "../day12/print.h" template<typename type> void my_swap (type& a, type& b) { type c = a; a = b; b = c; } template<typename iterator> void my_sort (iterator begin, iterator end) { iterator p = begin; iterator last = end; --last; for (iterator i = begin, j = last; i != j;) { while (! (i == p || *p < *i)) ++i; if (i != p) { my_swap (*p, *i); p = i; } while (! (j == p || *j < *p)) --j; if (j != p) { my_swap (*p, *j); p = j; } } iterator it = begin; ++it; if (p != begin && p != it) my_sort (begin, p); it = p; ++it; if (it != end && it != last) my_sort (it, end); } template<typename iterator, typename comparator> void my_sort (iterator begin, iterator end, comparator cmp) { iterator p = begin; iterator last = end; --last; for (iterator i = begin, j = last; i != j;) { while (! (i == p || cmp (*p, *i))) ++i; if (i != p) { my_swap (*p, *i); p = i; } while (! (j == p || cmp (*j, *p))) --j; if (j != p) { my_swap (*p, *j); p = j; } } iterator it = begin; ++it; if (p != begin && p != it) my_sort (begin, p, cmp); it = p; ++it; if (it != end && it != last) my_sort (it, end, cmp); } class CmpInt { public: bool operator() (int a, int b) const { return a > b; } }; int main (void) { int na[] = {13, 24, 22, 19, 44, 56, 88, 22}; vector<int> vi (na, na + 8); list<int> li (na, na + 8); my_sort (na, na + 8); print (na, na + 8); my_sort (vi.begin (), vi.end ()); print (vi.begin (), vi.end ()); my_sort (li.begin (), li.end (), CmpInt ()); print (li.begin (), li.end ()); return 0; }
stack.cpp
#include <iostream> #include <stack> #include <vector> using namespace std; int main (void) { stack<string, vector<string> > ss; ss.push ("吃饭"); ss.push ("喜欢"); ss.push ("偶"); while (! ss.empty ()) { cout << ss.top (); ss.pop (); } cout << endl; return 0; }