「算法刷题」c++中栈、队列和字符串的基本操作

c++ string的详细用法

string a=”123”;

1.在字符串末尾添加一个字符

a.push_back(‘3’); //结果为 a=”1233”;

2.在字符串末尾删除一个字符

a.pop_back(); //结果为 a=”12”;

3.assign()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//字符串变量
string a="123";
string b="456";

1.字符串直接赋值
a.assign(b); //等于a=b赋值,结果为 a="456"
a.assign("789");//结果为 a="789"

2.一个字符串的子串赋值给另一个字符串
a.assign(b,begin,len);
//从字符串b的第(begin)个字符开始向后数(len)个字符(包括begin)的字符串赋值给字符串a

例:
a.assign(b,0,1); //结果为 a="4"
a.assign(b,1,1); //结果为 a="5"
a.assign(b,0,2); //结果为 a="45";
a.assign(b,1,2); //结果为 a="56";
a.assign("123456",1,3); //结果为 a="234";
/*说明
*如果第三个参数大于字符串本身的长度,则赋值到该字符串末尾
*如:a.assign(b,1,4); 结果为 a="56";
*如果第二个参数大于字符串本身长度则赋值为空
*如:a.assign(b,3,4); 结果为 a="";
*第二个参数最大不能超过字符串长度加一,否则程序会运行错误。因为string字符串后面会有一个"\n"符号,这个符号虽然不算在字符串长度里面,但是会占一个字符的空间。所以超过字符串长度加一后会出现std::out_of_range的错误。
*/

3.从字符串的某一个字符串开始到结束赋值给另一个字符串
a.assign(b,begin);
//从字符串b的第begin字符串开始到字符串结束赋值给字符串a

a.assign(b,0); //结果为 a="456";
a.assign(b,1); //结果为 a="56";
a.assign(b,4); //error 这样会运行错误(同2) vs2019

4.从字符串开始到字符串的某一个字符赋值给另一个字符串
a.assign("123456",2);//结果为 a="12"
string c="123456";
a.assign(c,2); //结果为 a="3456"
//根据vs2019运行情况来看,如过第一个参数是字符串常量则按从头到第n个字符赋值,如果第一个参数是字符串变量的话,则从第n个字符开始到字符串结尾赋值(不知道其他编译会是怎么样的,vs2019是调用不同的重载函数)

5.用相同的n个字符给字符串赋值
a.assign(10,'b'); //结果为 a="bbbbbbbbbb";
a.assign(5,'c'); //结果为 a="ccccc";

6.template<class inputIterator> string& assign(inputIterator first,inputIterator last);
//使用这个函数需要引入#include<iterator>头文件
a.assign(istream_iterator<char>(cin), istream_iterator<char>());
//键盘输入123abcd
//结果为 a="123abcd";
/*注意
*该函数不接收空格换行等符号,最后(windows系统)按ctrl+z结束输入
*如输入以下符号(既有空格也有换行)
123abc ABC 哈哈 !@#$



defg)(-=<>-+/*


123654
最后结果为 a="123abcABC哈哈!@#$defg)(-=<>-+/*123654";
*/

7.使用迭代器赋值
a.assign(b.begin()+1,b.end()); //结果为 a="67";
a.assign(a.begin(),a.end()); //结果为 a="123";

## 4.append()

4.append()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
string a="1234";
string b="5678";

1.把两个string字符串相连接
a.append(b); //结果为 a="12345678";
a.append("56789");//结果 a="123456789";

2.从string字符串b的某一个字符开始到结束连接在string字符串a后面
a.append(b,1);//结果为 a="1234678";
a.append(b,0);//结果为 a="12345678";
a.append(b,3);//结果为 a="12348";
//注意第二个参数不能大于字符串b的长度加一,否则会出错,至于为什么请看我的上一篇assign函数的用法

3.从字符串b的某一个字符开始到结束连接在string字符串a后面
a.append("5678",1);//结果为 a="12345";
a.append("5678",2);//结果为 a="123456";
a.append("5678",0);//结果为 a="1234";
// 注意2,3的区别

4.把string的子串连接到另一个string后面
a.append("5678",0,1);
a.append(b,0,1); //结果为 a="12345";
a,append("5678",1,3);
a,append(b,1,3); //结果为 a="1234678";

5.在string字符串后面添加n个字符
a.append(10,'>'); //结果为 a="1234>>>>>>>>>>";

6.template<class inputIterator> string& append(inputIterator first,inputIterator last);
//需要引入头文件#include<iterator>
a.append(istream_iterator<char>(cin),istream_iterator<char>());
//从键盘输入abcd
//结果为 a="1234abcd";
/**注意
*该函数不接收空格换行等符号,最后(windows系统)按ctrl+z结束输入
*如输入以下符号(既有空格也有换行)
@#¥%………

按时到场 sdf 456

asd
最后结果为 a="1234@#¥%……按时到场sdf456asd";
*/

7.使用迭代器使string字符串相连接
a.append(b.begin()+1,b.end());//结果为 a="1234678";
a.append(a.begin(),a.end()); //结果为 a="12341234";

4.at()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
string a="abcd";

1.获取string字符串某一个字符
auto s=a.at(1); //结果为 s='b';
for (unsigned int i=0;i<a.size();i++)
{
cout << a.at(i) << endl;
}
/* 结果为
a
b
c
d
*/
//等同于a[i],但是at()会有下标检查,如果超出则抛出out_of_range

2.修改string字符串某一个字符
a.at(2)='1'; //结果为 a="ab1d";


5 front()与back()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string a="abcd";

1.获取字符串最后一个字符
auto b=a.back(); //结果为 b='d';

2.修改字符串最后一个字符
a.back()='!'; //结果为 a="abc!";

3.获取字符串第一个字符
auto b=a.front(); //结果为 b='a';

4.修改字符串第一个字符
a.front()='!'; //结果为 a="!bcd";

6.compare()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
string a="abcd";
string b="efgh";
string c="1fgh";
string d="fgh";
string e="123efg";

比较两个字符串的ASCII码,>0返回1,<0返回-1,相同,返回0
ASCII码比较是字符串的字符从前往后比较,如果之前的比较完成则后面的字符无需比较

1.直接比较两个字符串
auto number = a.compare(b); //结果为 number=-1;
auto number = b.compare(a); //结果为 number=1;
auto number = b.compare(b); //结果为 number=0;
auto number = a.compare(c); //结果为 number=1;
auto number = a.compare("abc"); //结果为 number=1;

2.一个字符串的子串与另一个字符串比较
auto number = b.compare(1,3,d); //结果为 number=0;
//字符串b从下标为1的字符开始的三个字符与字符串d比较,显然都是fgh,所以相等,返回0
auto number = b.compare(1,3,c); //结果为 number=1;
auto number = b.compare(1,3,"fgh"); //结果为 number=0;

3.一个字符串的子串与另一个字符串的子串比较
auto number = b.compare(1,3,c,1,3); //结果为 number= 0;
//字符串b从下标为1的地方开始的后3个字符是fgh,字符串c从下标为1的字符开始的后三个字符是fgh,所以相等
auto number = b.compare(0,3,e,3,3); //结果为 number=0;
//字符串b从下标为0的地方开始的后3个字符是efg,字符串e从下标为3的字符开始的后三个字符是efg,所以相等
auto number = b.compare(0,4,"1234efgh",4,4); //结果为 number=0;
//字符串b从下标为0的地方开始的后四个字符是efgh,字符串"1234efgh"从下标为4的字符开始的后4个字符是efgh,所以相等


7.copy()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
char *str = new char[64];
string a="12345abcdefg6789";

str[a.copy(str,7,5)]='\0';
// 结果为 str="abcdefg";

str[a.copy(str,7)]='\0';
// 结果为 str="12345ab";

delete[]str;

/*注意
*copy的第2,3个参数不能大于字符串str所能容纳的最长字符串长度
*/

8.data()与c_str() copy()的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string a="123456";

1.c_str(),data()可以生成一个const char* 的指针,可以指向一个空字符终止的地址。

const char* str=nullptr;
str=a.c_str(); //结果为 str="123456";
str=a.data(); //结果为 str="123456";

但是如果改变string a的值,str的值随之改变
a="abcedf";
cout<<str<<endl; //结果为 str="abcdef";

2.如果不想让其指针指向的值改变可以使用copy()函数(如果不知道copy()函数如何使用,请看我的上一篇copy()的使用方法)
char* str = new char[64];
str[a.copy(str, a.size(), 0)]='\0';
cout << str << endl; //结果为 str="123456";

//改变string a的值
a="abcd";
cout<< str <<endl; //结果为 str="123456";


9、erase()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
string a="123456789";

1.删除所有字符
a.erase(); //结果为 a="";

2.从字符串的某一个位置开始删除
a.erase(n) //从字符串的第n个字符开始删除
a.erase(3); //结果为 a="123";
a.erase(5); //结果为 a="12345";
a.erase(0); //等同于a.erase() a="";

3.从字符串的某一个位置开始,向后删除m个字符
a.erase(n,m); //从字符的第n个字符开始删除m个字符
a.erase(2,3); //结果为 a="126789";
a.erase(4,1); //结果为 a="12346789";

4.删除迭代器位置处的字符,并返回下一个字符的迭代器
auot iter=a.erase(a.begin()+1); //结果为 a="13456789";
cout<<*iter<<endl; //结果为 *iter=3

5.删除迭代器所指向的区间,并返回下一个字符的迭代器
auto iter=a.erase(a.begin()+1,a.end()-2);//结果为 a="189";
cout<<*iter<,endl; //结果为 *iter=8;

6.删除字符时常常与find()函数配合使用(find()函数的用法会在以后写出)
a.erase(a.find("56"),2); //结果为 a="1234789";


c++ 栈的基本操作:

​ 一种可以实现“先进后出(后进先出)”的存储结构

s.empty(); //如果栈为空则返回true, 否则返回false;
s.size(); //返回栈中元素的个数
s.top(); //返回栈顶元素, 但不删除该元素
s.pop(); //弹出/删除栈顶元素, 但不返回其值
s.push(); //将元素压入栈顶

在压栈的过程中,栈顶的位置一直在”向上“移动,而栈底是固定不变的。

image-20211027221030901

如果我们要把栈中的元素弹出来: 先入后出

image-20211027221100703

c++ queue 的基本操作

入队,如例:q.push(x); 将x 接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()