顺序容器

#include<iostream>
#include<vector>
#include<deque>
#include<list>
#include<forward_list>
#include<array>
#include<string>
#include<stack>
using namespace std;

//可以随机访问的有:vector,deque,array,string
//list, forward_list 不支持快速随机访问,但是删除和插入元素很快,deque在两端添加和删除元素的速度都是很快的

class noDefalut {
public:
	int get(int a) {
		return a;
	}
private:
	int a;
	int b;
};

void test() {
	//假定noDefault是一个没有默认构造函数的类型
	vector<noDefalut>v1(10, init);
	vector<noDefalut>v2(10); //错误,必须提供一个元素初始化器

	//容器类型成员
	list<string>::iterator iter;
	vector<int>::difference_type count;


	//begin 和end成员
	list<string> a = { "Milton", "Shakespeare", "Austen" };
	auto it1 = a.begin();
	auto it2 = a.rbegin();
	auto it3 = a.cbegin();
	auto it4 = a.crbegin();


	//当我们将一个容器初始化为另一个容器的拷贝时,我们要保证两个容器的类型和元素类型匹配

	//标准库array具有固定的大小
	array<int, 42>;
	array<string, 10>;
	array<int, 10>::size_type i;
	//array<int>::size_type j; 错误,array<int>不是一个类型
	array<int, 10>ia1;
	array<int, 10> ia2 = { 42 }; // 第一个元素为42,其他元素为0
	// 我们不可以对内置数组进行拷贝和对象赋值操作,但是可以对array进行
	int digs[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	//int cpy[10] = digs; 错误内置数组不支持拷贝操作
	array<int, 10>digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	array<int, 10>copy = digits;


	//使用assign(仅顺序容器)
	list<string> names;
	vector<const char*> oldstyle;
	//names = oldstyle; 错误容器类型不匹配
	names.assign(oldstyle.cbegin(), oldstyle.cend());
	list<string>slist1(1);
	slist1.assign(10, "Hiya");

	//使用swap
	vector<string>svec1(10);
	vector<string>svec2(24);
	swap(svec1, svec2);
	//与其他容器不同,对一个string调用swap会导致迭代器,引用和指针失效,与其他容器不同,swap两个array会真正交换他们的元素

	//push_back
	//除array和forward_list之外,每个顺序容器都支持push_back
	//list,forward_list,deque容器还支持名为push_front的类似操作
	list<int>ilist;
	for (size_t ix = 0; ix != 4; ix++) {
		ilist.push_back(ix);
	}

	//如果我们给insert一对迭代器,他们不能指向添加元素的目标容器

	//使用insert的返回值
	list<string>lst;
	auto iter = lst.begin();
	string word;
	while (cin >> word) {
		iter = lst.insert(iter, word);
	}

	//使用emplace操作
	/*
	emplace_front,emplace_back,emplace ,这些操作构造而不是拷贝元素,这些操作分别对应于push_front,insert,push_back
	当调用push或insert成员函数时,我们将元素类型的对象传递给他们,这些对象被拷贝到容器中,而我们调用emplace时,则是将参数传递给元素类型的构造函数
	emplace函数在容器中直接构造函数,传递给emplace函数的参数必须与元素类型的构造函数相匹配
	*/

	//访问成员函数返回的是引用
	vector<int>c;
	if (!c.empty()) {
		c.front() = 42;
		auto& v = c.back();
		v = 1024; 
		auto v2 = c.back(); //v2不是一个引用,它是c.back()的一个拷贝
		v2 = 0; //没有改变c中的元素
	}

	//下标操作和安全的随机访问
	vector<string>svec;
	cout << svec[0]; //运行时报错
	//cout >> svec.at[0]; 抛出一个out of range的异常


	//从元素内部删除一个奇数
	list<int>lst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto it = lst.begin();
	while (it != lst.end()) {
		if (*it % 2) {
			it = lst.erase(it);
		}
		else {
			++it;
		}
	}

	//删除多个元素
	lst.clear();
	lst.erase(lst.begin(), lst.end());

	//从forward_list中删除元素
	forward_list<int> flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto prev = flst.before_begin();
	auto curr = flst.begin();
	while (curr != flst.end()) {
		if (*curr % 2) {
			curr = flst.erase_after(prev);
		}
		else {
			prev = curr;
			++curr;
		}
	}


	//改变容器大小
	list<int> ilist(10, 42);
	ilist.resize(15);
	ilist.resize(25, -1);
	ilist.resize(5);

	//编写改变容器的循环程序
	vector<int> vi = { 0, 1, 2, 3, 4 ,5 ,6, 7, 8, 9 };
	auto iter = vi.begin();
	while (iter != vi.end()) {
		if (*iter % 2) {
			iter = vi.insert(iter, *iter);
			iter += 2;
		}
		else {
			iter = vi.erase(iter);
		}
	}

	//不要保存end返回的迭代器,必须在每次插入时重新调用end()
	/*begin = v.begin();
	while (begin != v.end()) {
		++begin;
		begin = v.insert(begin, 42);
		++beign;
	}*/

	//字符串操作
	//substr
	string s("hello world");
	string s2 = s.substr(0, 5);
	s.insert(s.size(), 5, '!');
	const char* cp = "stately pluump buck";
	s.assign(cp, 7); //s="stately"
	s.insert(s.size(), cp + 7); // s = stately plump buck
	string s("c++ prime"), s2 = s;
	s.insert(s.size(), "4th ed");
	s2.append("4th ed");
	s.erase(11, 3);
	s.insert(11, "5th");
	s2.replace(11, 2, "5th"); //从位置11开始删除两个字符,并插入5th


	//vector 收缩内存
	vector<int>s;
	for (int i = 0; i < 10000; i++) {
		s.push_back(i);
	}
	s.resize(3);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	vector<int>(s).swap(s);//匿名对象
	cout << s.capacity() << endl;
	cout << s.size() << endl;

	//vector预留空间
	vector<int>p;
	p.reserve(100000);
	int num = 0;
	int* q = NULL;
	for (int i = 0; i < 10000; i++) {
		p.push_back(i);
		if (q != &p[0]) {
			q = &p[0];
			num++;
		}
	}
	cout << num << endl;


	//string搜索操作
	string name("annabelle");
	auto pos1 = name.find("anne");
	string lowercase("annablele");
	pos1 = lowercase.find("Ann"); //pos1 = npos
	string numbers("0123456789");
	string name("r2d2"); // 返回name中第一个数字的下标
	auto pos = name.find_first_of(numbers);
	string dept("03423");
	auto pos = dept.find_first_not_of(numbers);


	//逆向搜索
	string river("mississippi");
	auto first_pos = river.find("is");
	auto last_pos = river.rfind("is");


	//数值转换
	int i = 42;
	string s = to_string(i);
	double = stod(s); //将字符串s转换为浮点数;
	//还有很多翻阅书328

	//容器适配器:一个容器适配器接受一种已有的容器类型,使其看起来像一张不同的类型
	stack<int>intstack;
	for (size_t ix = 0; ix != 10; ++ix) {
		intstack.push(ix);
	}
	while (!intstack.empty()) {
		int value = intstack.top();

	}

	
	
}




int main() {

	system("pause");
	return 0;
}
posted @ 2022-03-15 17:42  W-forever  阅读(19)  评论(0)    收藏  举报