STL学习总结

STL学习总结

一、 泛型程序设计及STL简介

       泛型程序设计是指编写一般化并可重复使用的程序。所谓泛型,其具有多种数据类型上皆可操作的含义,与模板类似。STL是Standard Template Library的简称,中文名标准模板库,是泛型程序设计的代表作品。STL包含很多计算机基本算法和数据结构,而且将算法与数据结构完全分离。STL有三个主要组件:容器、迭代器与算法。

二、 容器

       容器是存储其他对象的对象。STL的容器主要分为三大类:顺序容器、关联容器和容器适配器。

1. 顺序容器

       顺序容器是对象的线性集合,所有对象都是同一类型;三种基本顺序容器:向量(vector)、列表(list)、双向队列(deque)。

(1) Vector

       向(矢)量是一个多功能的、能够存放各种类型对象的类模板,其中的元素是连续存储的。简单地说,vector是数组的一种类表示,它提供了自动内存管理功能,可以动态地改变vector对象长度,并随着元素的添加和删除而增大和缩小。Vector提供了对元素的随机访问。在尾部添加和删除元素的时间是固定的,但在头部或中间插入和删除元素的复杂度为线性时间。
优点:尾部操作和随机访问速度快;缺点:不支持头插、任意位置删除和插入复杂度较高。

(2) List

       List模板类表示双向链表。除第一个和最后一个元素外,每个元素都与前后的元素相链接,可以双向遍历列表。与vector不同,list在链表中任一位置进行插入和删除的时间都是固定的。List不支持数组表示法和随机访问(没有重载下标运算符“[]”)。从容器中插入或删除元素后,不会移动已有的元素,只是修改链接信息,链表迭代器指向元素将不变。
优点:插入和删除的速度快;缺点:访问速度慢,不支持系统默认的sort排序,内存不连续。

(3) Deque

       Deque模板类表示在双端队列,是一种可以从双向进行操作的队列。Deque支持随机访问,可以实现向队列尾部或队列首部增添元素,以及从队列尾部或队列首部删除元素,但时间是固定的,而不想vector中那样是线性时间的。
优点:头尾插入和删除以及访问速度快;缺点:按位置插入和删除速度慢。

(4) 选择容器类型法则

如果程序要求随机访问元素,则应使用 vector 或 deque 容器。
如果程序必须在容器的中间位置插入或删除元素,则应采用 list 容器。
如果程序不是在容器的中间位置,而是在容器首部或尾部插入或删除元素,则应采用 deque 容器。
如果只需在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑在输入时将元素读入到一个 list 容器,接着对此容器重新排序,使其适合顺序访问,然后将排序后的 list 容器复制到一个 vector 容器。

2. 关联容器

       关联容器是对容器概念的另一个改进。关联容器将值与键关联在一起,并使用键来查找值。关联容器通常有用于确定数据放置位置的算法,以便能够快速检索信息,在查找时具有非常好的性能。但关联容器允许插入新元素,但不能指定元素的插入位置。因为关联容器中的元素是根据关键字存储的。
STL提供了4种关联容器:set、multiset、map和multimap。前两种是在头文件set中定义的,而后两种是在头文件map中定义的。

(1) Set

简介:STL set模拟了多个概念,它是关联集合,可反转,可排序,且键是唯一的,所以不能存储多个相同的值。
特点:储存同一类型的数据元素(这点和vector、queue等其他容器相同);每个元素的值都唯一(没有重复的元素);根据元素的值自动排列大小(有序性);无法直接修改元素;高效的插入删除操作。
Multiset类似于set,只是可能有多个值的键相同。

(2) Map

简介:映像容器(map)是一种特殊的集合,有时也称为字典(Dictionary)或关联数据(associative array)。map是一种key-value型容器,其中key是关键字,起到索引作用,而value就是其对应的值。Map中要求键key在容器中是唯一的,而其对应的value数据值则可以重复。
特点:map 的所有元素都是 pair,同时拥有实值value和键值key。pair 的第一元素为键值,第二元素为实值;map 不允许两个元素拥有相同的键值;不可以通过 map 的迭代器改变其元素的键值,可以修改元素的实值;当对 map 元素进行增加或删除操作后,原有的迭代器依然有效,被删除的元素的迭代器除外。
Multimap类似于map,其中允许出现相同的键值,但没有重载下标运算符“[]”。

3. 容器适配器

队列类型(queue):

       支持先进先出模式的数据存取。让低层展示典型的队列接口。不仅不允许随机访问队列元素,甚至不允许遍历队列。Queue把使用限制在定义队列的基本操作上,可以将元素添加到队尾,从对首删除元素、查看队首和队尾的值、检查元素数目和测试队列是否为空。如果要使用队列中的值,应首先使用front()来检索这个值,然后使用pop()将它从队列中删除。

栈容器(stack):

       支持先进后出模式的数据存取。给底层提供典型的栈接口。不仅不允许随机访问栈元素,甚至不允许遍历栈。把使用限制在定义栈的基本操作上,即可以将压入推到栈顶、从栈顶弹出元素、查看栈顶的值、检查元素的数目和测试栈是否为空。如果要使用栈中的值,应首先使用top()来检索这个值,然后使用pop()将它从栈中删除。

优先级队列容器(priority_queue):

       每次从队列中取出的应是具有最高优先级的元素,而优先级则与每一个元素的值相关联。支持操作与queue相同,但最大元素被移到队首,内部底层类是vector。

三、 迭代器

       迭代器是指针的泛化,是一种检查容器内元素并遍历元素的可带泛型数据类型。迭代器使算法独立于使用的容器类型。所有的第一类容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作;迭代器可以执行++操作;通过对一个迭代器的解引用操作(*),可以访问到容器所包含的元素。在利用迭代器访问元素之前,先要定义迭代器。

四、 两个编程题:

1.使用vector存储用户从键盘输入的n个整数,利用stl中的算法,统计出现次数大于2的数据。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
	int n;
	int i=0;
	int j=0;
	cout << "please enter the number of n:" << endl;
	cin >> n;
	vector<int>v1(n);
	vector<int>v2(n);
	vector<int>v3(n);
	vector<int>::iterator pos;
	for (i = 0; i < n; i++)
	{
		cin >> v1[i];
	}
	for (i = 0; i < n; i++)
	{
		v2[i] = count(v1.begin(), v1.end(), v1[i]);
		if (v2[i] > 2)
		{
			v3[j] = v1[i];
			j++;
		}
	}
	pos = unique(v3.begin(), v3.end());
	cout << *pos;
	return 0;
}
  1. 定义一个英汉翻译词典,存储英文单词和中文词语,提供插入、查找、修改、删除的操作。在此基础上,实现一个简单的英汉翻译器。main函数中输入中文,输出对应的英文单词。
//dictionary.h
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include<iostream>
#include<map>
#include<string>

using namespace std;

class Dictionary
{
public:
	void out();//全部输出
	void del(string word);//删除单词
	void add(string word, string explanation);//增加单词
	string tran(string);//翻译
private:
	map<string, string>dic;
};

#endif
//dictionary.cpp
#include<iostream>
#include<map>
#include<string>
#include"dictionary.h"

using namespace std;
//全部输出
void Dictionary::out()
{
	map<string, string>::iterator it;
	for (it = dic.begin(); it != dic.end(); it++)
	{
		cout << it->first << ":" << it->second << endl;
	}
}
//删除单词
void	Dictionary::del(string word)
{
	dic.erase(word);
}
//增加单词
void Dictionary::add(string word, string explanation)
{
	dic.insert(make_pair(word, explanation));
}
//翻译
string Dictionary::tran(string word)
{
	if (dic.find(word) != dic.end())
	{
		return dic[word];
	}
	else
	{
		return string("no this word");
	}
}
//translation.cpp
#include<iostream>
#include<map>
#include<string>
#include"dictionary.h"

using namespace std;

int main()
{
	Dictionary dt;
	//添加
	dt.add(string("one"), string("一,一个"));
	dt.add(string("two"), string("二,二个"));
	dt.add(string("China"), string("中国"));
	dt.add(string("has"), string("有"));
	dt.add(string("dut"), string("大连理工大学"));
	dt.add(string("ssdut"), string("大连理工大学软件学院"));
	//全部输出
	cout << "字典中词汇如下:" << endl;
	dt.out();
	cout << endl;
	//翻译
	cout << "China的意思是:" << endl << dt.tran(string("China")) << endl;
	cout << "one的意思是:" << endl << dt.tran(string("one")) << endl;
	cout << "two的意思是:" << endl << dt.tran(string("two")) << endl;
	cout << "has的意思是:" << endl << dt.tran(string("has")) << endl;
	cout << "dut的意思是:" << endl << dt.tran(string("dut")) << endl;
	cout << "ssdut的意思是:" << endl << dt.tran(string("ssdut")) << endl;
	cout << endl;
	//删除
	dt.del(string("two"));
	cout << "删除two后,字典的词汇如下:" << endl;
	dt.out();
	cout << endl;
	return 0;
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值