STL标准模板库简介h

STL诞生

  • 可重复利用
  • c++面向对象和泛型编程思想,目的就是重复性的提升
  • 大多数情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作
  • 为了建立数据结构和算法的一套标准,诞生了STL

STL基本概念

  • STL标准模板库(standard Template Library)
  • DTL从广义上分为 容器(container)算法(algorithm)迭代器(iterator)
  • 容器和算法之间通过迭代器进行无缝链接
  • STL几乎所有的代码都采用了模板或者模板函数

STL六大组件

  • STL大体分为六大组件,分别为:容器,算法,迭代器,仿函数,适配器,空间配置器
  1. 容器:各种数据结构,如vector,list,deque,set,map等数据结构
  2. 算法:各种常用算法,如sort,find,copy,each等
  3. 迭代器:扮演了容器和算法之间的胶合剂
  4. 仿函数:行为类似函数,可作为算法的某种策咯
  5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
  6. 空间适配器:负责空间的配置与管理

STL中容器,算法,迭代器

容器:放东西用的

STL容器就是将运用最广泛的一些数据结构实现出来

常用的数据结构有:数组,链表,树,栈,队列,集合,映射表等

这些容器分为序列式容器和关联式容器两种:

  • 序列式容器:强调值的排列,序列式容器中的每个元素均有固定的位置
  • 关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系

算法:问题的解法(algorithms)

算法分为质变算法和非质变算法

  • 质变算法:是指运算过程中会更改区间内元素的内容,例如拷贝,替换,删除等
  • 非质变算法:是指运算过程中,不会更改区间内的全部内容,例如查找,计数,遍历,寻找极值等

 

迭代器:容器算法之间的粘合剂

提供一种方法,使之能够依序寻访某个容器中所含的元素,而又无需暴漏该容器的内部表示方式

每个容器都有自己的 专属迭代器

迭代器的使用非常类似于指针

迭代器种类:

常用的容器中迭代器种类为双向迭代器,和随机访问迭代器

容器算法迭代器的初步认识

vector存放内置数据类型

  • 容器:vector
  • 算法:for_each
  • 迭代器:vector<int>::iterator

#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
void myprint(int val)
{
	cout<<val<<endl;
}
void test01()
{
	//创建了一个vector
	vector<int> v;
	//向容器中插入数据
	v.push_back (10);
	v.push_back (20);
	v.push_back (30);
	v.push_back (40);
	v.push_back (50);
	//通过迭代器访问容器中的数据
	vector<int>::iterator itBegin=v.begin ();//v.begin()起始迭代器,指向容器中第一个元素
	vector<int>::iterator itend=v.end ();//结束迭代器,指向容器中最后一个元素的下一个位置

	//第一种遍历方式
	while(itBegin !=itend )
	{
		cout<<*itBegin <<endl;
		itBegin ++;
	}
	cout<<"///"<<endl;
	//第二种遍历方式
    for(vector<int>::iterator it=v.begin ();it!=v.end ();it++ )
	{
		cout<<*it<<endl;
	}
	cout<<"//"<<endl;
	//第三种遍历 利用stl中的遍历算法 for_ezch
	for_each(v.begin (),v.end (),myprint);//利用回调
}
int main()
{
   test01();
}

for_each()底层实现

vector中存放自定义数据类型

看代码:

#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class animal
{
public:
	animal(string name,int age)
	{
		
		this->_name =name;
		this->_age =age;
	}
	string _name;
    int  _age;
};
void test01()
{
	//创建一个自定义类型的容器
	vector<animal >v;
	//向容器中添加数据
	animal p1("aaa",10);
	animal p2("bbb",20);
	animal p3("ccc",30);
	animal p4("ddd",40);
	animal p5("eee",50);

	v.push_back (p1);
	v.push_back (p2);
	v.push_back (p3);
	v.push_back (p4);
	v.push_back (p5);
	
	//遍历容器中的数据
	//注意*it完成解引用后市寄存器的类型,也就是animal类型
	for(vector<animal>::iterator it=v.begin ();it!=v.end();it++)
	{
		cout<<"姓名: "<<(*it)._name <<"年龄"<<(*it)._age <<endl;
		//it是一个指针,通过箭头也可以访问
		cout<<"姓名:"<<it->_name <<"年龄"<<it->_age <<endl;
	}

}
//存放自定义类型的指针
void test02()
{
	//创建一个自定义类型的容器
	vector<animal* >v;
	//向容器中添加数据
	animal p1("aaa",10);
	animal p2("bbb",20);
	animal p3("ccc",30);
	animal p4("ddd",40);
	animal p5("eee",50);

	v.push_back (&p1);
	v.push_back (&p2);
	v.push_back (&p3);
	v.push_back (&p4);
	v.push_back (&p5);

	//遍历容器
	for(vector<animal *>::iterator pit=v.begin ();pit!=v.end();pit++)
	{
		//(*pit)是animal类型的指针
		cout<<"姓名:"<<(*(*pit))._name <<"年龄:"<<(*(*pit))._age <<endl;
		cout<<"姓名:"<<(*pit)->_name <<"年龄:"<<(*pit)->_age <<endl;
	}

}
int main()
{
	//test01();
	test02();
}

vector容器嵌套(类似于二维数组)

#include<iostream>
#include<vector>
using namespace std;
void test01()
{
	vector<vector<int>> v;
	//创建 小容器
	vector <int> v1;
	vector <int> v2;
	vector <int> v3;
	vector <int> v4;

	for(int i=0;i<4;i++)
	{
		v1.push_back (i+1);
		v2.push_back (i+2);
		v3.push_back (i+3);
		v4.push_back (i+4);
	}
	//将小容器插入到大容器中
	v.push_back (v1);
	v.push_back (v2);
	v.push_back (v3);
	v.push_back (v4);
	//通过大容器来遍历所有数据,(*it)是容器---vector<int>
	for(vector <vector<int> > ::iterator it=v.begin ();it!=v.end();it++)
	{
		for(vector <int>::iterator sit=(*it).begin ();sit!=(*it).end();sit++)
		{
			cout<< *sit <<" ";
		}
		cout<<endl;

	}


}
int main()
{
	test01();
}

string容器

本质:

  • string是c++风格的字符串,而string 本质上是一个类

string和char *的区别:

  • cha r* 是一个指针
  • string是一个类,类的内部封装了char*,管理这个字符串,是一个char *型的容器

特点:

  • string 内部封装了很多成员方法
  • 例如:查找find(),拷贝copy(),删除delete,替换replace ,插入insert
  • string 管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责

string 构造函数

构造函数原型

  • string()          //创建一个空的字符串,例如string str;
  • string (const char *s)    //使用字符串s 初始化
  • string(const string &str)//使用一个string对象初始化另外一个string 对象
  • string(int n,char c)//使用n个字符c初始化
#include<iostream>
#include<vector>
#include<string>
using namespace std;
void test01()
{
	string s1;//默认构造
	const char*str="hello world";
	string s2(str);
	cout<<"s2:"<<s2<<endl;
	string s3(s2);
	cout<<"s3:"<<s3<<endl;

	string s4(10,'a');
	cout<<"s4:"<<s4<<endl;

}
int main()
{
	test01();
}

strint 的赋值操作

 

#include<iostream>
#include<vector>
#include<string>
using namespace std;
void test01()
{
	string str1;
	str1="hello world";
	cout<<"str1="<<str1<<endl;
	string str2;
	str2=str1;
	cout<<"str2="<<str2<<endl;

	string str3;
	str3='a';
	cout<<"str3="<<str3<<endl;

	string str4;
	str4.assign ("hello nihao");
	cout<<"str4="<<str4<<endl;

	string str5;
	str5.assign ("hello nihao",5);
	cout<<"str5="<<str5<<endl;

	string str6;
	str6.assign (str5);
	cout<<"str6="<<str6<<endl;

	string  str7;
	str7.assign (10,'w');
	cout<<"str7="<<str7<<endl;

}
int main()
{
	test01();
}

string 字符串拼接

实现在字符串末尾拼接字符串

#include<iostream>
#include<vector>
#include<string>
using namespace std;
void test01()
{
	string str1="我";
	str1+="爱看剧";
	cout<<"str1="<<str1<<endl;

	str1+=':';
	cout<<"str1="<<str1<<endl;

	string str2="wangzhe";
	str1+=str2;
	cout<<"str1="<<str1<<endl;

	string str3="i ";
	str3.append ("love ");
	cout<<"str3="<<str3<<endl;

	str3.append ("you too",3);
	cout<<"str3="<<str3<<endl;

	str3.append (str2);
	cout<<"str3="<<str3<<endl;

	str3.append (str2,4,3);
	cout<<"str3="<<str3<<endl;


}
int main()
{
	test01();
}

string 查找和替换

  • 查找:查找指定字符串是否存在
  • 替换:在指定的位置替换字符串

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
	string str1="abcdefghijk";

	int pos=str1.find("de");//默认为0位置
	if(pos==-1)
	{
		cout<<"未找到字符串"<<endl;
	}
	else
	{
		cout<<"pos="<<pos<<endl;  //3  下标从0开始  没有返回-1
	}
	pos=str1.rfind ("de");
	cout<<"pos="<<pos<<endl;
	//rfind和find的区别,,rfind从右往左查找,fin是从左往右查找
}
void test02()
{
	string str1="abcdefg";
	//从1号位置起三个字符串替换为1111
	str1.replace (1,3,"1111");
	cout<<"str1="<<str1<<endl;
}
int main()
{
	test01();
	test02();
}

总结:

  • find查找从左往右,rfind相反
  • find查找到字符串后返回查找的第一个字符的位置,找不到返回-1
  • replace在替换时,要指定从那个位置开始,多少个字符,替换成什莫样的字符串

string 字符串比较

字符串比较是按照字符串的ascll码进行比较

= 返回0

>返回1

<返回-1

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
	string str1="zello";
	string str2="hello";
	if(str1.compare (str2)==0)
	{
		cout<<"str1==str2"<<endl;
	}
	else if(str1.compare (str2)>0)
	{
		cout<<"str1>str2"<<endl;
	}
	else
	{
		cout<<"str1<str2"<<endl;
	}

}

int main()
{
	test01();
	//test02();
}

主要是比较相等

string中单个字符存取

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
	string str="hello";
	cout<<"str="<<str<<endl;
	//通过[]访问单个字符
	//通过at访问单个字符
	for(int i=0;i<str.size ();i++)
	{
		cout<<str[i]<<" ";
	}
	cout<<endl;
	for(int i=0;i<str.size ();i++)
	{
		cout<<str.at(i)<<" ";
	}
	cout<<endl;
	//修改单个字符
	str[0]='x';
	cout<<"str="<<str<<endl;

	str.at(1)='y';
	cout<<"str="<<str<<endl;

}


int main()
{
	test01();
	//test02();
}

string 中的插入和删除

注:插入删除的起始下标都是从0开始的

 

string字串

 

#include<iostream>
#include<vector>
#include<string>
using namespace std;
//查找
void test01()
{
	string str="helloworld";
	string sub=str.substr(1,2);//没有参数的话,默认截取全部
	cout<<"sub="<<sub<<endl;
}
//实际操作

void test02()
{
	string email="fooooood@163.com";
	//从邮箱地址中获取用户信息
	int pos=email.find("@");//9
	string usname=email.substr (0,pos);
	cout<<"usname:"<<usname<<endl;

}


int main()
{
	//test01();
	test02();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值