Coding In C++, Day13

标准模板库STL(续)


六、堆栈
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;
};

/*
 * 适配器练习- stack
 *
 * */
#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;
}


七、队列
queue   底层容器deque/list (p.s.不可以是vector,因为vector没有提供pop_front)
push    push_back
pop     pop_front
front   front
back    back
size    size
empty   empty
...
queue<int, list<int> > qi;
queue<string> qs; // 缺省底层容器deque

/*
 * 适配器练习- queue
 * */
#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;
}


八、优先队列(priority_queue)
优者先出
底层容器:vector/deque/list,缺省deque
通过类型实参以比较器的形式定义比较规则

/*
 * 适配器练习- priority queue
 *
 * */
#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;
}


九、映射(map)
1.key-value对(pair)的容器,通过pair表示key-value对。
post script:关于pair
template<typename FIRST, typename SECOND>
class pair {
prublic:
  ...
  FIRST first;
  SECOND second;
};
2.key唯一且升序。
3.支持下标运算符,可以用[key]访问value。
4.可以通过比较器类型自定义key升序的规则。

/*
 * map练习
 * */
#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', "张飞"));//构造一个pair的对象放入map对象里
	mc['D'] = "刘备";
	mc['E'] = "曹操";
	mc['C'] = "关羽";
	mc['D'] = "黄忠";//因为key唯一且升序,所以这里会造成'D'不再与"刘备"形成映射
	mc.insert (pair<char, Candidate> ('A', "马超"));//使用map的成员函数insert时候,insert判断出key已经与其他value形成映射,那么会忽略此次的insert
	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;
}


/*
 *练习:编写程序,统计一个文本文件中每个单词出现的频率。按照词汇表的顺序打印输出。
 *apple : 2
 *beijing : 2
 *c++ : 3
 *...
 * */
#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;
    }
};

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;
	
	return 0;
}


十、集合

/*
 *set练习
 */
#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;
}


十一、多重映射
key可重复,升序,迭代时key相同的元素相邻。

/*
 *multimap练习
 */
#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);//upper_bound(key)成员函数返回和参数key相匹配的所有记录中最后一条记录的下一条记录的迭代器
		int sum = 0;
		for (; it != end; ++it)
			sum += it->second;
		cout << key << " : " << sum << endl;
	//	--it;
	}
	return 0;
}


十二、多重集合

/*
 *multiset练习
 */
#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;
}


十三、泛型算法
1.STL中包含60种泛型算法,其中包含23种非修改算法,如find,37种修改算法,如sort。
2.STL中的泛型算法多数都会迭代器实现对容器元素的访问。
3.STL中的泛型算法凡是涉及到比较大小的算法,都支持两种比较方案——“<”运算符和比较器函数对象。
4.除了STL中的容器以外,程序员也可以使自定义的容器,获得STL泛型算法的支持,只要改自定义类型能够支持此算法对迭代器的使用规则即可。

/*
 *练习:假设现在有任意两个容器,请实现一个泛型的容器拷贝函数,用将一个容器中数据拷贝到另一个容器中。
 */
#include <vector>
#include <deque>
#include <list>

template<typename iterator>
void print(iterator begin, iterator end)
{
        while (begin != end) {
                cout << *begin++ << ' ' << flush;
        }
        cout << endl;
        return 0;
}

template<typename IT1, typename IT2>
void my_copy (IT1 begin, IT1 end, IT2 to) {
	while (begin != end)
		//*(to++) = *(begin++);
		*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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值