C++标准库---string、容器

1.string

#include <iostream>
#include <string>
1.1构造
//赋值构造
string str = "zxm";
//无参构造,构造一个空字符串,构造之后可以通过=进行赋值
string str2;
//用char *构造
string str3("zxm");
//重复字符构造,输出11个a
string(11,'a');
//拷贝构造  str2和str5内容是一样的
string str5(str2);
//移动拷贝   str2没有内容,移动到str6里去了
string str6(move(str2));
//用指定范围内的字符进行构造,从第四个下表开始,取三个给str7
string str7(str2,4,3);
//字符串拼接
string str8+str2+"111";
1.2 元素访问
string str="hello world";
str[1]='E';
str.at(1)='E';
//第一个字符
cout << str.front() << endl;
//最后一个字符
cout << str.back() << endl;
//data() c_str   获取数据
cout << str.data() <<endl;
1.3容量操作
//判断是否为空  返回0、1   true、false
string str = "hello world";
cout << boolalpha << str3.empty() <<endl;
//字符串中的大小和长度
cout << str.size() << endl;
cout << str.length() << endl;
//字符串对象最大的容量
cout str.max_size() << endl;
//截取前几个字符
cout << str.resize(10) << endl;
//已经分配的内存容量
cout << str.capacity() << endl;
//分配内存大小
str.reserve();
//没有用到的内存释放掉
str.shrink_to_fit();
1.4迭代器

迭代器:为容器类提供统一的遍历接口,不用管容器底层内存管理方式。

1.(正向)迭代器 iterator

2.(正向)只读迭代器 const_iterator

3.反向迭代器 reverse_iterator

4.反向只读迭代器 const_reverse_iterator

string str = "hello world";
//指向第一个位置
string::iterator it = str.begin();
//输出h
cout << *it <<endl;
//输出l
it+=3;
cout << *it < endl;
//可以修改,如果是只读迭代器的话,就不可以修改了
*it ='E'
//循环遍历
for(;it!=str.end();it++){
    cout << *it <<endl;
}

反向迭代器:

string::reverse_iterator it = str.rbegin();
//循环遍历
for(;it!=str.rend();it++){
    cout << *it <<endl;
}
1.5string比较相关操作
//==
string str="hello world";
string str2="Hello World";
cout << std::boolalpha <<(str==str2) <<endl;   //返回true  or  false
//compare
cout << str.compare(str2) <<endl;
//判断是否以指定的内容开始或者结尾
cout << boolalpha << str.starts_with("hello") << endl;
cout << boolalpha << str.ends_with("jpg") <<endl;   //可以判断后缀名
//判断字符串中是否含有某些内容
cout << boolalpha << str.contains("txt") <<endl;
1.6插入和删除操作
string str="hello world";
//在现有的字符串基础上再加E
str.push_back("E");
//把最后一个字符串给删除
str.pop_back();
//在字符串基础上追加内容,就是在最后开始追加
str.append(3,'A');  //追加三个A
str.append(3,'A').append(2,'B');
str.append(str2);
//从第三个字符开始追加
str.append(str2,3);
str.append("Nice");
str.append(str2.begin(),str2.begin()+3);
//insert() 在指定位置插入字符
str.insert(2,3,'C');  //从索引为2开始插入三个C
str.insert(2,str2,5,2);
//清除字符串的所有内容
str.clear();
//清楚指定位置
str.erase(2,2);   //从2开始 清除两个字符
str.erase(str.begin()+2);  //从str开始的第二个字符开始清除
ser.erase(str.begin()+2,str.begin()+5);   //清除[2,5)字符
1.7 替换子串
string str = "hello world";
string str2="北国风光";
string str3 = "hello Cpp";
str.replace(2,1,str2) ;  //索引为2的字符替换一个字符  替换成str2    he北国风光lo world
//取字符串
cout << str.substr(3) << endl;  //从索引3开始提取
cout << str.substr(3,2) << endl;  //从索引3开始提取2个字符
1.8查找
string str = "AAABBBCCCDDD"
//返回查到的第一个字符的索引号   找不到返回npos(-1)
cout << str.find("AA") <<endl;
int index = str.find("KDKD");
if(string::npos==index){
    cout << "没找到" << endl;
}else{
    cout <<  "找到了" <<endl;
}
//从后面往前找
str.rfind();
//找最先出现的字符的位置  
str.find_first_of("EECD");
//返回B的索引
str.find_first_not_of("AAA");
//从后往前找
find_last_of();
find_last_not_of();
1.9其他操作
to_string();  //将数组转化为string
str+to_string(12);
//将string转换为数字
cout << stoi(str2,&n,16) << endl;  //将str2转换为16进制的数字,返回转换的个数n
cout << n << endl;
//将string转换为浮点型:DOUBLE,float
cout << stod(str2) << endl;
stof;
//计算hash值
cout << hs(str) <<endl;
1.10 string_view
const char *s="望长城内外";
string_view sv = s;

这样 sv和s都是指向同一个地址。否则,正常的string会再会创建另一个地址把内容存进去 节省了内存空间

//移除六个字节
sv.remove_prefix(6);
cout << sv << endl;
//从后面移除字节数
sv.remove_suffix(6);

2.容器

2.1array
//头文件
#include<array>
//创建
array<int,5> arr = {1,2,3,4,5};
cout << arr[0] <<endl;
cout << arr.at(0) <<endl;
//填充   将这五个位置都给填充上
array<int,5> arr;   //可以存储自己定义的数据类型
arr.fill(111);  
for(auto &n :arr){
    cout  << n << endl;  //输出:111 111 111 111 111
}
//使用迭代器遍历
array<int,5>::iterator it = ar.begin();
for(;it!=arr.end();it++){
    cout  << *it << endl;
}
2.2vector

动态的连续数组 大小是变化的

#include<vector>
//声明
vector<int> vec;     //int 可以替换成对象
cout << vec.size() << endl;
cout << vec.capacity() << endl;
for(auto &n : vec){
    cout << n << "\t";
}
//分配了三个元素的大小 用100来填充
vector<int> vec(3,100);
//分配了10个元素的大小 用0来填充
vector<int> vec(10);
#include<vector>
//声明
vector<int> vec(10);  //分配十个内存大小
//插入
vec.push_back(10);
 //输出地址
cout << (uintptr_t)vec.data() << endl; 
//插入
vec.push_back(122);
//输出地址
cout << (uintptr_t)vec.data() << endl;   
 //大小
cout << vec.size() << endl;
 //分配的大小
cout << vec.capacity() << endl;   
for(auto &n : vec){
    cout << n << "\t";     //输出
}
//分配了三个元素的大小 用100来填充
vector<int> vec(3,100);
//分配了10个元素的大小 用0来填充
vector<int> vec(10);

1.调用无参构造进行初始化

调用了三参构造和移动构造,移动构造将临时变量移动到地址

vector<User> vec(3);  
//在末尾插入user
vec.push_back(User(1,"tom",22)); 

2.调用拷贝构造

vector<User> vec(3);  
User u1(1,"tom",22);
vec.push_back(u1);

User u2(1,"Jey",22);
vec.push_back(u2);

首先是u1的三参构造,然后就是拷贝对象,因为要拷贝到里面那个位置上

首先是u2的三参构造,然后就是拷贝对象。然后u1又进行了一次对象拷贝

内存分配的问题。给u2的内存分配完成后,将u1拷贝到u2的前面的那个位置

3.能不能不进行拷贝或者移动

vec.emplace_back(2,"jj",21);  //插入

只进行了一次三参构造

vec.emplace_back(); 

只进行了一次无参构造

vec.emplace(vec.begin()+1,3,"Le",4);
2.3.单向链表-forward_list

声明:

#include<forward_list>
forward_list<int> fs = {2,4,1,9,3}
forward_list<int> fs2 = {5,8,1,6,9}
forword_list<int>::iterator it = fs.begin();
it++;

只能通过自增的方式一步一步的往后移

擦除元素

it++;
it++;
fs.erase_after(it); // 擦除it后面的元素  9被擦除了
for(auto &i : fs){
    cout << i << "\t";
}

合并元素

fs.merge(fs2);   //fs和fs2合并在一起  但是是无序的
//可以先排序,再合并 
fs.sort();
fs2.sort();
fs.merge(fs2);   //这样合并之后就是有序的了   把fs2合并到fs里面  fs2就没有内容了

指定位置合并

fs.splice_after(it,fs2);   //在1后面把指定的链表插入进去

移除指定的值

fs.remove(8);   //移除8

//根据条件移除对应的内容

bool pre(const int &n){
    return n<4;
}
fs.remove_if(pre);  //把<4的内容移除掉  对fs的每个元素用提供的函数做判断
fs.remoce_if([] (const int& n){return n<4});

//升序

fs.sort();

//逆序,降序

bool cmp(const int &a,const int &b){
    return a>b;
}
fs.sort(cmp);
fs.sort([](const int &a,const int &b){return a<b});
greater<int> gt;
fs.sort(gt);
fs.sort(greater<int>());

//移除连续重复的元素

fs.unique();
2.4.list双链表

和单链表类似

list<int> ls = {1,3,4,5,6,7}
list<int>::iterator it = ls.begin();
it++;
it++;
it--;
cont << *it <<endl;
2.5.栈stack

引入头文件

#include<stack>
stack<string> str_stack;
str_stack.push("zzz");  //入栈   简单的数据类型用push
//取栈顶数据
string str = str_stack.top();
//栈顶元素删除
str_stack.pop();
cout << str << endl;

//出栈

while(!str_stack.empty()){
    string str = str_stack.top();
    str_stack.pop();
    cout << str << endl;
}
2.6.队列queue

引入头文件

#include<queue>
queue<const char *>q;
q.qush("张三");
q.emplace("赵六"); //多个数据

获取第一个元素

const char *s=q.front();
//出队
q.pop();
cout << s << endl;

循环一次出队

while(!q.empty()){
    const char *s=q.front();
	//出队
	q.pop();
	cout << s << endl;
}
2.7.双端队列priority_queue 优先队列
priority_queue<int> q;
q.push(10);
q.push(20);
q.push(15);
while(!q.empty()){
    auto top = q.top(); //获取队首元素
    q.pop();
    cout << top <<endl;
}
输出:20  15  10   按照从大到小输出

可以从小到大输出

priority_queue<int,vector<int>,greater<int>> q;   //参数:类型,容器,默认vector,比较器
q.push(10);
q.push(20);
q.push(15);
输出: 10  15  20 
//如果存入的数据是自定义的类,那就需要重载一个<运算符  就可以用默认的比较器比较大小
priority_queue<Persion> q;
q.emplace(60,"Tom");
q.emplace(70,"Jerry");
q.emplace(65,"Lee");
//根据年龄比较大小
//重载<运算符
bool operator < (const Persion &p1,const Persion &p2){
    return p1.getAge() < p2.getAge();
}
输出: 70  65   60

自定义比较器

方式一:模仿less定义的比较器

struct Comp{
    bool operator()(const Persion &p1,const Persion &p2) const{
        return p1.getAge() < p2.getAge();
	}
};
priority_queue<Persion,vector<Persion>,Comp> q;

方式二:定义普通比较函数

bool cmp(const Persion &p1,const Persion &p2){
    return p1.getAge() < p2.getAge();
}
typefdef bool (*cmp2) (const Persion &p1,const Persion &p2);  //宏定义函数指针
priority_queue<Persion,vector<Persion>,cmp2> q(cmp);

方式三:通过lambda表达式定义比较函数

auto cmp3 = [](const Persion& p1,const Persion& p2){
    return p1.getAge() < p2.getAge();
};
priority_queue<Persion,vector<Persion>,decltype(cmp3)> q(cmp3);   //decltype自动类型推导
2.8.set

不重复

#include<set>
set<int> st {1,3,4,3}  //输出:1  3  4   重复的删除掉了
vector<int> vec = {1,1,2,2,3,3,4,4,5,5};
set<int> st2(vec.begin(),vec.end());   //输出:1 2 3 4 5

判断两个元素是否相等

如何两个对象a和b相互不比较小于对方:!a<b && !a>b 那么认为他们等价

//插入元素节点
st.insert(0);

//把指定元素提取出来

set<int>::node_type node = st.extract(3);  //把3提取出来    
cout << node.value() << endl;

//合并集合 合并的是原先集合没有的

st.marge(st2)

返回元素的个数

st.count()

find:查找指定的值

返回指定的值的下边界,返回的是对应值的下标 返回的是迭代器

cout << *st.lower_bound(3) <<endl;

返回指定的值的上边界,返回的是对应值的下标 返回的是迭代器

cout << *st.upper_bound(3) <<endl;

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值