C++ STL使用方法

本文深入探讨了C++标准库中的关键数据结构和算法,包括vector、string、map、set、list、stack、queue等容器的使用方法,以及sort、merge、reverse等算法的实现细节。通过实例展示了各种容器的初始化、基本操作和其他高级功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Algorithm

参考: https://blog.youkuaiyun.com/yo_bc/article/details/53337839

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
void print(int &elem){	//有无&均可 
	cout << elem << " ";
}
//qsprt必须用这种格式定义比较函数,像bj定义qsort传入参数会出错
// *和(int *)是同一优先级运算符,但结合方向是从右向左
int cmp(const void *a, const void *b){ 
	return *(int *)a - *(int *)b;
}
int bj(int a, int b){ 
	return a > b;
}
int main(){
	int a[] = {0, 3, 9, 1, 4, 8, 5, 2, 6, 7};
	
	/*traverse*/
	for_each(a, a+10, print);
	cout << endl;
	
	
	/*swap*/
	char x = 'X', y = 'Y';
	swap(x, y);
	printf("x = %c, y = %c\n", x, y);
	
	/*reverse*/
	int a[4]={1,2,3,4};
	reverse(a,a+4);
	char str[] = "abcdefgh";
    reverse(str,str+8);	//前闭后开 
    string s = "abcdefg";
    reverse(s.begin(),s.begin()+8);
    reverse(s.begin(),s.end());
    cout << str << endl;
    vector<int> v={1,2,3,4,5};
	reverse(v.begin(),v.end());//v的值为5,4,3,2,1

 
 	/*sort*/
	//快排模板函数,数组下标从0开始,即排序下标为0-9的元素
	//qsort,sort时间复杂度都是O(n*log(n)),但实际中sort速度一般比qsort快!!
	int a[] = {0, 3, 9, 1, 4, 8, 5, 2, 6, 7};
	for_each(a, a+10, print);
	qsort(a, 10, sizeof(a[0]), cmp);
	// sort(aa, aa+10);
	//不传入第三个参数默认sort为升序排序
	sort(aa, aa+10, bj);

	//struct sort
	/*struct node {
		int index;
		string name;
	}q[10];
	bool cmpD(node x,node y) { //注意参数类型
		return x.index>=y.index;
	}
	sort(q,q+10,cmpD);*/
	
	/*max min*/
	cout << endl << max(66,88) << endl << min(66,88) << endl;
	
	/*unique*/
	// sort words alphabetically so we can find the duplicates 
	sort(words.begin(), words.end()); 
 	vector<string>::iterator end_unique =  		   unique(words.begin(), words.end()); 
 	words.erase(end_unique, words.end());
	
	//二路归并,头文件algorithm
	int ak[] = {1, 9, 5, 4, 7};
	int ka[] = {3, 6, 2, 8, 0};
	int kk[15];
	sort(ak, ak+5);
	sort(ka, ka+5);
	merge(ak, ak+5, ka, ka+5, &kk[1]);
	
	for_each(ak, ak+5, print);
	cout << endl;
	for_each(ka, ka+5, print);
	cout << endl;
	for_each(kk+1, kk+11, print);
	cout << endl;
	return 0;
}

vector

  • 初始化
#include <vector>
vector< typeName > v1;       //默认v1为空,故以下的赋值是错误的v1[0]=5;
vector<typeName>v2(v1); 或v2=v1;或vector<typeName> v2(v1.begin(), v1.end());//v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被扩充为v1.size()。
vector< typeName > v3(n,i);//v3包括n个值为i的typeName类型元素
vector< typeName > v4(n); //v4含有n个值为0的元素
int a[4]={0,1,2,3,3}; vector<int> v5(a,a+5);//v5的size为5,v5被初始化为a的5个值。后一个指针要指向将被拷贝的末元素的下一位置。
vector<int> v6(v5);//v6是v5的拷贝
vector< 类型 > 标识符(最大容量,初始全部值);
  • 基本操作
v.push_back(t)  //入vector,尾巴
v.pop_back()    //出vector,尾巴
v.back()   		//获取vector尾部元素
v.front()       //获取vector头部元素
v.size()        //返回容器中数据的个数,
v.empty()       //推断vector是否为空
v[n]            //返回v中位置为n的元素
v.clear()       //删除容器中的全部元素。
  • 其他操作
v.resize(2*v.size)              
v.resize(2*v.size, 99) //将v的容量翻倍(并把新元素的值初始化为99)
v.insert(pointer,number, content)    //向v中pointer指向的位置插入number个content的内容。
v.insert(pointer, content)
v.insert(pointer,a[2],a[4]) //将a[2]到a[4]三个元素插入。
v.erase(pointer1,pointer2) //删除pointer1到pointer2中间(包含pointer1所指)的元素。
Eg.
	v5.insert(v5.begin()+1,9); //在第二个位置插入新元素
	v5.erase(v5.begin() + 3);  //删除第四个元素
	v5.insert(v5.begin() + 1, 7,8); //连续插入7个8

v1==v2          //推断v1与v2是否相等。
!=<<=>>=   // 保持这些操作符惯有含义。
vector<typeName>::iterator p=v1.begin( ); //p初始值指向v1的第一个元素。*p取所指向元素的值。对于const vector<typeName>仅仅能用vector<typeName>::const_iterator类型的指针訪问。
p=v1.end( ) //p指向v1的最后一个元素的下一位置。

string

  • 初始化
include <string>

string s1;      //初始化字符串,空字符串
string s2 = s1; //拷贝初始化,深拷贝字符串
string s3 = "hello world"; //直接初始化,s3存了字符串
string s4(10, 'a'); //s4存的字符串是aaaaaaaaaa
string s5(s4); //拷贝初始化,深拷贝字符串
string s6("hello world"); //直接初始化
string s7 = string(6, 'c'); //拷贝初始化,cccccc
string str , getline(cin, str);//获取整一行
  • 基本操作
string s1 = s2 + s3;//将两个字符串合并成一个
string s1 = s2 + "hello world";
s1 = s2;//用一个字符串来替代另一个字符串的对用元素
s.empty()
s.size()
s[n]
s1 == s2, s1!=s2 //大小写敏感
<,<=,>,>=  //大小比较
  • 判断字符函数
isalpha(c) 
islower(c) 
isupper(c)
tolower(c)
toupper(c)

isdigit(c)
isspace(c)  
isalnum(c)  //字母或者数字

map

key - value的对应

参考: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html

  • 基本操作
#include <map>
map<int,string> mapStudent;

/*遍历*/
//method 1
map<int,string>::iterator iter;
for(iter=mapStudent.begin(); iter!= mapStudent.end();iter++){
	cout << iter->first << " " << iter->second << endl;
}

//method 2
int mapSize = mapStudent.size();
for(int i= 1; i <= mapSize;i++){
	cout << mapStudent[i] << endl;
}


/*插入操作*/
//method 1 : pair插入 (VC-#pragma warning (disable:4786) )
mapStudent.insert(pair<int, string>(1,"1111");
mapStudent.insert(pair<int, string>(2,"2222");
mapStudent.insert(pair<int, string>(3,"3333");

//method 2: value_type数据
mapStudent.insert(map<int, string>::value_type(1,"1111"));
mapStudent.insert(map<int, string>::value_type(2,"2222"));
mapStudent.insert(map<int, string>::value_type(3,"3333"));

//method 3: 数组插入
mapStudent[1]="1111";
mapStudent[2]="2222";
mapStudent[3]="3333";
// 第一种和第二种方法效果一样, 当key一样的时候, 不能插入
//而数组的方式可以, 后面覆盖前面的值

//如何判断插入成果
pair<map<int, string>::iterator, bool> insertState;
insertState =  mapStudent.insert(map<int, string>::value_type(1,"1111"));
if(insertState.second == true) //insert success!
else // insert fail!


/*查找*/
map<int, string>::iterator iter;
iter= mapStudent.find(1);
if(iter != mapStudent.end()) cout << iter->second<< endl;
else cout <<"Can't find" << endl;

/*删除*/

//method 1
map<int, string>::iterator iter;  
iter = mapStudent.find(1);  
mapStudent.erase(iter);  

// method 2
int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0  
  
mapStudent.erase( mapStudent.begin(), mapStudent.end() );  //一下代码把整个map清空   
  • 排序问题
#include <iostream>  
#include <string>  
#include <map>  
using namespace std;  
  
typedef struct tagStudentinfo  
  
{  
  
       int      niD;  
  
       string   strName;  
  
       bool operator < (tagStudentinfo const& _A) const  
  
       {     //这个函数指定排序策略,按niD排序,如果niD相等的话,按strName排序  
  
            if(niD < _A.niD) return true;  
  
            if(niD == _A.niD)  
  
                return strName.compare(_A.strName) < 0;  
  
        return false;  
  
       }  
  
}Studentinfo, *PStudentinfo; //学生信息  
  
int main()  
  
{  
  
    int nSize;   //用学生信息映射分数  
  
    map<Studentinfo, int>mapStudent;  
  
    map<Studentinfo, int>::iterator iter;  
  
    Studentinfo studentinfo;  
  
    studentinfo.niD = 1;  
  
    studentinfo.strName = "student_one";  
  
    mapStudent.insert(pair<Studentinfo, int>(studentinfo, 90));  
  
    studentinfo.niD = 2;  
  
    studentinfo.strName = "student_two";  
  
    mapStudent.insert(pair<Studentinfo, int>(studentinfo, 80));  
  
    for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)  
  
        cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl;  
  
    return 0;  
}  

set

set与vector类似, 但是删除了重复,以及自动排序了

#include<set>    
#include<iostream>    
using namespace std;
int main()
{
    set<int>s;
    set<int> s1{9,8,1,2,3,4,5,5,5,6,7,7 }; //自动排序,从小到大,剔除相同项
    set<string> s2{ "hello","sysy","school","hello" }; //字典序排序
    s1.insert(9); //有这个值了,do nothing
    s2.insert("aaa"); //没有这个字符串,添加并且排序
   
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        s.insert (x);
    }
    set<int>::iterator it;
    for(it=s.begin ();it!=s.end ();it++)
    {
        printf("%d\n",*it); 
    }

 
   
    //s.end()没有值
     cout<<"s.begain()   "<<*s.begin ()<<endl;
    //lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器
    cout<<"lower_buond  3  "<<*s.lower_bound (3)<<endl;
    
    //upper_bound()--返回大于某个值元素的迭代器
    cout<<"upper_bound  3  "<<*s.upper_bound (3)<<endl;

    //find()--返回一个指向被查找到元素的迭代器
    cout<<"find()  3   "<<*s.find (3)<<endl;
	int a[] = {1,2,3};
    //Example:
    /*set<int> s1(a,a+3);
    set<int>::iterator iter;
    if((iter = s1.find(2)) != s1.end())
    {
        cout<<*iter<<endl;//输出为2
    }
    */

    cout<<"s.size()  "<<s.size ()<<endl;
    return 0;
    /*删除*/
	s.erase(iterator)  ,删除定位器iterator指向的值
	s.erase(first,second),删除定位器first和second之间的值
	s.erase(key_value),删除键值key_value的值


}
  • 自定义比较函数:
  1. 元素不是结构体:
struct myComp  
{  
    bool operator()(const your_type &a,const your_type &b)  
    [  
        return a.data-b.data>0;  
    }  
}  
set<int,myComp>s;  
......  
set<int,myComp>::iterator it;  
  1. 元素是结构体:
struct Info  
{  
    string name;  
    float score;  
    //重载“<”操作符,自定义排序规则  
    bool operator < (const Info &a) const  
    {  
        //按score从大到小排列  
        return a.score<score;  
    }  
}  
set<Info> s;  
......  
set<Info>::iterator it;  

list

list就是链表.
list是一个双向链表,而单链表对应的容器则是foward_list。
list即双向链表的优点是插入和删除元素都比较快捷,缺点是不能随机访问元素。
初始化方式就大同小异了,跟vector基本一样。要想用list先加个头文件list。

#include <iostream>
#include <list>
#include <string>

using namespace std;

template <typename T>
void showlist(list<T> v)
{
    for (list<T>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it;
    }
    cout << endl;
}

int main()
{
    list<int> l1{ 1,2,3,4,5,5,6,7,7 };
    showlist(l1);
    list<double> l2;
    list<char> l3(10);
    list<int> l4(5, 10); //将元素都初始化为10
    showlist(l4);
    system("pause");
    return 0;
} 

值得注意的是,list容器不能调用algorithm下的sort函数进行排序,因为sort函数要求容器必须可以随机存储,而list做不到。所以,list自己做了一个自己用的排序函数,用法如下:

list<int> l1{ 8,5,7,6,1,2,3,4,5,5,6,7,7 };
l1.sort();

stack

  • 基本操作
#include <stack>
s.push(x);
s.pop(). //注意:出栈操作只是删除栈顶的元素,并不返回该元素。
s.top();
s.empty(). //当栈空时返回true。
s.size();
s1==s2  //若成立,表明s1中的每个元素都等于s2的对应元素,返回true或是false

queue

  • 基本操作
#include<cstdlib> 
#include <queue>
queue<int>q1;
queue<double>q2;

q.push(x) //将x元素接到队列的末端;
q.pop() //弹出队列的第一个元素,并不会返回元素的值;
q.front()//访问队首元素
q.back();//访问队尾元素
q.size();//访问队中的元素个数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值