C++常用数据结构及其相关函数


字符串string

#include <string>

/*构造函数*/
string s(str); //生成字符串为str的复制品
string s(str, strbegin,strlen); //将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值
string s(cstr, char_len); //以C_string类型cstr的前char_len个字符串作为字符串s的初值
string s(num ,c); //生成num个c字符的字符串
string s(str, stridx); //将字符串str中从下标stridx开始到字符串结束的位置作为字符串初值

/*大小*/
s.size(); 
s.length(); //返回string对象的字符个数,他们执行效果相同
s.max_size(); //返回string对象最多包含的字符数,超出会抛出length_error异常
s.capacity(); //重新分配内存之前,string对象能包含的最大字符数

/*查找*/
strchr(s1, ch); //返回一个指针,指向字符串s1中字符ch的第一次出现的位置
strstr(s1, s2); //返回一个指针,指向字符串s1中字符串s2的第一次出现的位置
s.back(); //返回最后一个字符的引用
int num = count(str.begin(),s.end(),'a'); //统计str中字符a出现次数(algorithm头文件)
s1.find(s2); //查找s2在s1中出现的首位置,若没找到则==s1.npos或string::npos

/*插入*/
s.push_back(char); //尾部插入一个字符char
s.insert(pos,char); //在指定位置pos前插入字符char

/*截取*/
s=s.substr(int begin,int length); //从下标为begin位置截取长度为length
s=s.substr(int begin); //从下标为begin位置截取到字符串尾

/*拼接*/
s.append(string s); //s尾部拼接字符串s
s.append(int n,char c); //s尾部拼接n个字符c
strcpy(s1, s2); //复制字符串 s2 到字符串 s1
s1=s2; //复制字符串 s2 到字符串 s1
strcat(s1, s2); //连接字符串 s2 到字符串 s1 的末尾。连接字符串也可以用 + 号
string str = str1 + str2; //操作符+

/*删除*/
iterator erase(iterator p); //删除字符串中p所指的字符
iterator erase(iterator first, iterator last); //删除字符串中迭代器区间[first,last)上所有字符
string& erase(size_t pos = 0, size_t len = npos); //删除字符串中从索引位置pos开始的len个字符
void clear(); //删除字符串中所有字符

/*替换*/
string& replace(size_t pos, size_t n, const char *s); //将当前字符串从pos索引开始的n个字符,替换成字符串s
string& replace(size_t pos, size_t n, size_t n1, char c); //将当前字符串从pos索引开始的n个字符,替换成n1个字符c
string& replace(iterator i1, iterator i2, const char* s); //将当前字符串[i1,i2)区间中的字符串替换为字符串s

/*比较*/
//常见的比较操作符(>,>=,<,<=,==,!=)|根据“当前字符特性”将字符按字典顺序,从前向后进行逐一比较。字典排序靠前的字符小,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小(前面减后面)
s1.compare(s1Position, s1Length, s2, s2Position, s2Length); //支持多参数处理,支持用索引值和长度定位子串来进行比较。返回一个整数来表示比较结果(0相等 1大于 -1小于) (A的ASCII码是65,a的ASCII码是97)
strcmp(s1, s2); //s1和s2相同,返回0;s1<s2,返回负值;s1>s2,返回正值

/*遍历*/
//下标遍历
for( int i = 0; i < s1.size() ; i++ ) cout<<s1[i];
//正向迭代器
string::iterator iter = s1.begin();
for(;iter < s1.end();iter++) cout<<*iter;
//反向迭代器
string::reverse_iterator riter = s1.rbegin(); 
for(;riter<s1.rend();riter++)  cout<<*riter;

可以将string当作数组,执行相关操作,例如pop_back(),push_back()等

集合set

  • set中元素插入过程是按排序规则插入,所以不能指定插入位置。
  • set不可以直接存取元素。(不可以使用at.(pos)与[]操作符)。
  • multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次。
  • 不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素
集合底层实现是否有序数值是否可重复数值是否可改变查询增删
std::set红黑树有序O(logn)O(logn)
std::multiset红黑树有序O(logn)O(logn)
std::unordered_set哈希表无序O(1)O(1)

优先使用unordered_set(查询和增删效率是最优);集合有序选set;有序且有重复数据选multiset

#include <set>

//构造函数
set<int> s;     //以int型为例 默认按键值升序
set<int,greater<int>> s;  //降序排列
set<type> s(begin, end); //将[beg, end)区间中的元素拷贝给本身
set<type> s1(const set &s2); //拷贝构造函数

//成员函数
int x;
s.clear(); //清除所有元素
s.erase(x); //删除x元素,返回0或1,0表示set中不存在x
s.erase(iterator); //删除定位器iterator指向的值
s.erase(first,second); //删除定位器first和second之间的值
s.erase(key_value); //删除键值key_value的值

s.count(x); //返回键值为X的元素个数
s.insert(x); //在集合中插入元素x
s.inset(first,second); //将定位器first到second之间的元素插入到s中
s.empty(); //如果集合为空,返回true

s.get_allocator(); //返回集合的分配器
s.find(x); //返回一个指向被查找到元素x的迭代器,没找到返回end()
s.lower_bound(x); //返回一个迭代器,指向第一个键值不小于x的元素
s.upper_bound(x); //返回一个迭代器,指向第一个键值大于x的元素
s.equal_range(x); //返回集合中与给定值x相等的上下限的两个
				//返回一对迭代器,分别表示第一个大于或等于键值x的元素,和第一个大于键值x的元素
				//这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值

s.key_comp(); //返回一个用于元素间值比较的函数
s.value_comp(); //返回一个用于比较元素间的值的函数
s.size(); //集合中元素的数目
s.max_size(); //返回集合能容纳的元素的最大限值
s.swap(); //交换两个集合变量

s.begin(); //返回指向第一个元素的迭代器
s.end(); //返回指向最后一个元素后面的迭代器
s.rbegin(); //返回指向集合中最后一个元素的反向迭代器
s.rend(); //返回指向集合中第一个元素的反向迭代器

参考:multiset用法总结

映射map

  • map是一种关联式容器,包含“关键字/值”对
映射底层实现key是否有序key是否可重复key是否可改变查询增删
std::map红黑树有序O(logn)O(logn)
std::multimap红黑树有序O(logn)O(logn)
std::unordered_map哈希表无序O(1)O(1)
#include <map> 

//构造函数
// 定义一个map对象
map<int, string> mapStudent;
//用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));
//用insert函数插入value_type数据
mapStudent.insert(map<int, string>::value_type(001, "student_one"));
//用"array"方式插入
mapStudent[123] = "student_first";
mapStudent[456] = "student_second";

//查找
// find 返回迭代器指向当前查找元素的位置否则返回map::end()位置
iter = mapStudent.find("123");
if(iter != mapStudent.end())
       cout<<"Find, the value is"<<iter->second<<endl;
else cout<<"Do not Find"<<endl;

//删除 清空
//迭代器刪除
iter = mapStudent.find("123");
mapStudent.erase(iter);
//关键字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
//用迭代器范围刪除 : 把整个map清空
mapStudent.erase(mapStudent.begin(), mapStudent.end());//等同于mapStudent.clear()

//大小
int nSize = mapStudent.size(); //返回map中元素的个数
m.max_size(); //返回可以容纳的最大元素个数

//其他操作
m.insert(); //插入元素
m.count(); //返回指定元素出现的次数(因为key值不会重复,所以只能是1或0)
m.empty(); //如果map为空则返回true
m.swap(); //交换两个map
m.get_allocator(); //返回map的配置器
m.key_comp(); //返回比较元素key的函数
m.lower_bound(); //返回键值>=给定元素的第一个位置
m.upper_bound(); //返回键值>给定元素的第一个位置
m.value_comp(); //返回比较元素value的函数

//迭代器
m.begin(); //返回指向map头部的迭代器
m.end(); //返回指向map末尾的迭代器
m.rbegin(); //返回一个指向map尾部的逆向迭代器
m.rend(); //返回一个指向map头部的逆向迭代器
m.equal_range(); //返回特殊条目的迭代器对

数组vector

  • vector的大小有两个维度:size(常用来遍历vector)和capicity(vector底层数组,也就是普通数组的大小)
  • insert时,如果已经大于capicity,capicity会成倍扩容(重新申请一个二倍于原数组大小的数组,然后把数据都拷贝过去,并释放原数组内存),但对外暴漏的size仅仅+1
  • 可以定义确定大小的vector,不允许其动态扩容
#include <vector>

//初始化
//若是int类型,默认初始化为0;若为string类型,默认为空字符串
vector<type> v; //空Vector,执行默认初始化
vector<type> v2<v1>; //v2中包含v1所有元素的副本
vector<type> v2=v1; //等价于v2<v1>
vector<type> v(n, value>; //v中包含n个重复元素,每个元素的值均为value
vector<type> v(n); //v中包含n个重复执行了值初始化的对象
vector<type> v(a,b,c,...); //赋予初始值
vector<type> v={a,b,c,...}; //等价于上句

//添加
v.push_back(elem); //在数组尾部添加一个数据
v.emplace_back(elem); //在数组尾部添加一个数据
//push_back()方法要调用构造函数和拷贝构造函数,即要先构造一个临时对象,然后将这个临时副本拷贝或移动到容器最后面
//emplace_back()则是直接在容器的尾部创建这个元素,省去了拷贝或移动元素的过程
v.insert(pos, elem); //在指定位置pos之前插入一个新元素elem
v.insert(pos, n, elem); //在指定位置pos之前插入n个新元素elem
v.insert(pos, first, last); //在指定位置pos之前插入其他容器(不仅限于vector)中[first,last)范围内的所有元素

//删除
v.pop_back(); //删除最后一个元素(size减一,capacity不变)
v.clear(); //清空vector(size变为0,capacity不变)
v.erase(pos); //删除指定位置pos处的一个元素
v.erase(begin, end); //删除[begin, end)范围内中所有元素(capacity不变)
v.remove(val); //删除和指定元素值val相等的所有元素(size和capacity都不变)

//访问
operator[pos] //返回指定位置pos的引用
v.at(pos); //得到编号位置的数据
v.front(); //返回第一个元素的引用
v.back(); //返回最后一个元素的引用,不检查该元素是否存在
v.begin(); //返回第一个元素的指针(即地址)
v.end(); //返回最后一个元素的下一个的指针(指向一个不存在的元素)

//大小
v.size(); //当前使用数据的大小
v.max_size(); //最大可允许的vector元素数量值
v.capacity(); //vector实际能容纳的大小
v.empty(); //判断vector是否为空
c.resize(num); //重新指定队列的长度
c.reserve(sz); //保留适当的容量sz

//交换
v1.swap(v2); //v1与v2交换
swap(v1, v2); //同上

栈stack

  • 栈不提供走访功能,也不提供迭代器(iterator)
  • 栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用哪种容器来实现栈的功能),所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器
  • 底层容器使用不同的容器,导致栈内数据在内存中不是连续分布
  • 栈的底层实现可以是vector、deque、list,默认是以deque(双向队列)
函数说明
push()将x入栈,O(1)
top()获得栈顶元素,O(1)
pop()弹出栈顶元素,O(1)
empty()检测stack是否为空(true-空 false-非空),O(1)
size()返回stack内元素的个数,O(1)

队列

#include <queue>
函数说明
queue<int> q;普通声明
empty()测试是否为空队列
size_type size()返回队列长度
front()返回对头元素
back()返回队尾元素
void push(const T& x)插入一个元素到队尾
void pop()删除队列下一个元素

优先队列(priority_queue)

  • 对外接口从队首取元素,从队尾添加元素,看起来就是一个队列,其实是个
  • 队列中最大的元素总是位于队首。出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队
  • 缺省情况下利用max-heap(大顶堆)完成对元素的排序,这个大顶堆是以vector为表现形式的complete binary tree(完全二叉树),按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则
//定义结构,使用运算符重载,自定义优先级
struct cmp1{  
    bool operator ()(int &a,int &b){  
        return a>b;//最小值优先  
    }  
};  
struct cmp2{  
    bool operator ()(int &a,int &b){  
        return a<b;//最大值优先  
    }  
};
priority_queue<int,vector<int>,cmp1(cmp2)> q;

//也可以用自带函数
prority_queue<int,vector<int>,greater<int> >
//注意要用空格不然>>会被判定为右移运算符
priority_queue<int,vector<int>,less<int> >

双端队列(deque)

  • 和vector很类似,采用动态数组来管理元素。但它不像vector一样把所有对象保存在一个连续的内存块,而是多个连续的内存块
  • 两端都能够快速插入和删除元素(vector只能在尾端操作)
  • 支持随机访问,即[]和at(),可以在内部进行插入和删除操作(相对较慢,因为所有元素都要被移动)
  • deque不提供容量操作,即capacity()和reverse()。其他均与vector相同
#include <deque>

//添加
dque.push_back(elem); //在数组尾部添加一个数据
dque.push_front(elem); //在数组头部添加一个数据
dque.insert(pos, elem); //在指定位置pos之前插入一个新元素elem
dque.insert(pos, n, elem); //在指定位置pos之前插入n个新元素elem
dque.insert(pos, first, last); //在指定位置pos之前插入其他容器(不仅限于vector)中[first,last)范围内的所有元素

//删除
dque.pop_back(); //删除最后一个元素
dque.clear(); //清空vector
dque.erase(pos); //删除指定位置pos处的一个元素
dque.erase(begin, end); //删除[begin, end)范围内中所有元素

//访问
operator[pos] //返回指定位置pos的引用
dque.at(pos); //得到编号位置的数据
dque.front(); //返回第一个元素的引用
dque.back(); //返回最后一个元素的引用,不检查该元素是否存在
dque.begin(); //返回第一个元素的指针(即地址)
dque.end(); //返回最后一个元素的下一个的指针(指向一个不存在的元素)

//大小
dque.size(); //当前使用数据的大小
dque.max_size(); //最大可允许的vector元素数量值
dque.empty(); //判断vector是否为空
dque.resize(num); //重新指定队列的长度
dque.resize(num,elem); //重新指定队列的长度,若size变大,则用elem作为默认值补齐

//交换
dque1.swap(qdue2);
swap(dque1, qdue2);

单调队列

C++中没有直接支持单调队列,可以用deque实现(力扣题目

  • pop(value):如果要移除的元素value等于单调队列的队首元素(即max),那么弹出队首元素,否则不用任何操作(因为队列里压根就没有value)
  • push(value):如果添加的元素value大于队尾元素(即min),那么弹出队尾元素,直到push的元素≤队尾元素为止
  • front():即返回队列的最大值
//deque实现一个单调队列
class monotoniQue{
    deque<int> q;
    public:
        //若要移除的元素不是当前窗口中的最大值(即front),就没什么影响
        void pop(int n){
            if(!q.empty() && n==q.front())
                q.pop_front();
        }
        void push(int n){
            while(!q.empty() && n>q.back()) q.pop_back();
            q.push_back(n);
        }
        int front(){
            //front 即 max
            return q.front();
        }
};

链表

双向链表list

  • 可以高效地插入、删除元素
  • 不能随机存取,不支持at函数与operator[]操作符
#include <list>

//带参构造
list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身(注意该区间是左闭右开的区间)
list(n,elem); //构造函数将n个elem拷贝给本身
list(const list &lst); //拷贝构造函数

//添加 移除
list.push_back(elem); //在容器尾部加入一个元素
list.pop_back(); //删除容器中最后一个元素
list.push_front(elem); //在容器开头插入一个元素
list.pop_front(); //从容器开头移除第一个元素


//存取
list.front(); //返回第一个元素
list.back(); //返回最后一个元素

//插入
list.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置
list.insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
list.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值

//删除
list.clear(); //移除容器的所有数据
list.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置
list.erase(pos); //删除pos位置的数据,返回下一个数据的位置
lst.remove(elem); //删除容器中所有与elem值匹配的元素

//赋值
list.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间
list.assign(n,elem); //将n个elem拷贝赋值给本身
list& operator=(const list &lst); //重载等号操作符
list.swap(lst); //将lst与本身的元素互换

//大小
list.size(); //返回容器中元素的个数
list.empty(); //判断容器是否为空
list.resize(num); //重新指定容器的长度为num。若容器变长,则以默认值填充新位置;若容器变短,则末尾超出容器长度的元素被删除
list.resize(num, elem); //重新指定容器的长度为num。若容器变长,则以elem值填充新位置;若容器变短,则末尾超出容器长度的元素被删除

//反转
list.reverse(); //反转链表

//迭代器
list.begin(); //返回容器中第一个元素的迭代器
list.end(); //返回容器中最后一个元素之后的迭代器
list.rbegin(); //返回容器中倒数第一个元素的迭代器
list.rend(); //返回容器中倒数最后一个元素的后面的迭代器

二叉树

C++中map、set、multimap,multiset的底层实现都是平衡二叉搜索树,所以map、set的增删操作时间时间复杂度是logn

类型

  • 满二叉树:只有度为0的结点和度为2的结点,并且度为0的结点在同一层。深度为k时,有2^k-1个节点
  • 完全二叉树:除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点
  • 平衡二叉树:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1
  • 二叉搜索树:有序树,若左子树不空,则左子树上所有结点的值均小于它的根结点的值;若右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树

存储方式

  • 顺序存储(数组)
    在内存中连续分布。若父节点索引为i,则其左孩子索引为i*2+1,右孩子索引为i*2+2
  • 链式存储(指针)
    通过指针将分布在各个地址的节点串联在一起。每个节点有一个左指针和一个右指针
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

遍历方式

  • 深度优先(递归法/迭代法):

前序遍历(中左右)力扣题目

//递归法
void preorderTraversal(TreeNode* root, vector<int> &vec){
	if(root==NULL) return;
	vec.push_back(root->val); //中
	traverse(root->left,vec); //左
	traverse(root->right,vec); //右
}

中序遍历(左中右)力扣题目

//递归法
void preorderTraversal(TreeNode* root, vector<int> &vec){
	if(root==NULL) return;
	traverse(root->left,vec); //左
	vec.push_back(root->val); //中
	traverse(root->right,vec); //右
}

后序遍历(左右中)力扣题目

//递归法
void postorderTraversal(TreeNode* root, vector<int> &vec){
	if(root==NULL) return;
	traverse(root->left,vec); //左
	traverse(root->right,vec); //右
	vec.push_back(root->val); //中
}
  • 广度优先(迭代法)
    层次遍历

指针&引用


常用库函数

<bits/stdc++.h>

  • 几乎包含所有的可用到的C++库函数,不需要在写一大堆vector、string、map、stack……
  • 不属于GNU C++库的标准头文件,在部分情况下可能会失败
  • 使用它将包含许多不必要的东西,并增加编译时间
  • 这个头文件不是C++标准的一部分,因此是不可移植
  • 编译器每次编译翻译单元时都必须实际读取和分析每个包含的头文件,应该减少这类头文件的使用

algorithm

#include<algorithm>
//在vector list set map等容器中使用

swap(a, b); //交换a和b

reverse(iterator begin, iterator end); //反转在[begin, end)范围内的顺序,没有返回值

remove(begin, end, num);
//删除容器中在[begin, end)范围内,和指定元素num值相同的所有元素
//不改变容器的size和capacity
//搭配erase()函数使用,改变size
 
 //不稳定排序
sort(vec.begin(), vec.end()); //默认从小到大排序
sort(vec.begin(), vec.end(),less<int>()); //从小到大排序
sort(vec.begin(), vec.end(),greater<int>()); //从大到小排序
sort(vec.begin(), vec.end(),cmp); //自定义比较函数
bool cmp(int a,int b) { return a<b; }
//稳定排序
stable_sort(vec.begin(), vec.end()); 

binary_search(vec.begin(), vec.end(), elem);
//用于在有序的集合中搜索,若集合无序,应当自行sort后再使用搜索
//有返回true,否则false。比find()更高效

int max_calue =  max_element(vec.begin(), vec.end());
//取两个指针之间的最大值,需要定义大小比较运算符

replace(); //替换某位置的文件

merge(v.begin(), v.end(), v1.begin(), v1.end(), v2.begin());
//两个容器合并到一个新容器,依然是一个有序序列

int num=count(vec.begin(),vec.end(),target); //统计target元素出现的次数
int num=count_if(vec.begin(),vec.end(),cmp); //统计满足cmp的元素个数
//例如:bool cmp(int a) {return a>10;}

//search():对比容器中是否存在某个子序列,若存在返回指向子序列起始处的iterator,否则指向容器末尾
iterator it=search(v1.begin(),v1.end(),v2.begin(),v2.end());//找到v2中元素在v1中第一次出现的位置
iterator it=search_n(v.begin(),v.end(),n,target);//寻找v中首次连续出现n次target的位置
iterator it=search_n(v.begin(),v.end(),n,target,[](int i,int j){return i>j;});//寻找首次连续出现n次大于target的位置

//find():若容器中元素是一个类,要查找类就需要重载==
class cls
{
public:
    cls(void); 
    ~cls(void);
	int ele;
    bool cls::operator==(const cls &tar) const { return (age == tar.ele); }
}
 
list<cls> lst; //向list容器中添加cls类元素
 
cls target; // 要查找的cls对象
target.ele = 50;
list<cls>::iterator it = find(list.begin(), list.end(), target);

//find_if():查找满足某些自定义条件的元素
/*例1*/
map<int, char*> m;
auto it = find_if(m.begin(), m.end(),
 [&](const pair<int, char*> &item) {return item->first == 0/*期望值*/;});
/*例2*/
 typedef struct strc
{
    int a;
    int b;
}strc;
vector<strc> strc_vec;
auto it= find_if(strc_vec.begin(), strc_vec.end(), [](strc myStruct)
{
     return myStruct.a > 2 && myStruct.b < 8;/*期望范围*/
});

//字符串转换大小写
string S="HELLO";
transform(S.begin(),S.end(),S.begin(),::tolower);
string s="hello";
transform(s.begin(),s.end(),s.begin(),::toupper);

string

#include<string>

void *memset(void *s, int c, size_t n);
//初始化函数,将s所指向的某一块内存中的前n个字节的内容全部设置为指定的值c
//返回一个指向存储区s的指针

stoi(const string s,int begin,int n);
//将 n 进制的字符串s从begin位置开始转化为十进制
//参数是const string类型;会做范围检查,默认在int范围内,超出会runtime error

stoi(str, , ); //字符串str从0位置开始到末尾的二进制转换为十进制

str=str.replace(str.find("a"),2,"#");  //从第一个a位置开始的两个字符替换成#
str=str.replace(str.begin(),str.begin()+5,"#"); //用#替换从begin位置开始的5个字符
str=str.replace(pos,len,str,subpos,sublen); //用substr中的指定字符串替换str中的指定字符串
//例如:用substr的第一个1出现位置开始的4个字符,替换str中从0位置开始,长度为5的字符串
//str=str.replace(0,5,substr,substr.find("1"),4);
str = str.replace(pos,len,n,ch);   //用重复n次的ch字符替换的替换从pos位置开始,长度为len的字符串

cctype

#include<cctype> //c中是ctype.h

//单个字符转换大小写字母
char c='c',A='A';
c=toupper(c); //同c+=32;
A=tolower(A); //同A-=32;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值