《C++ STL —— 数据结构与算法实现》 第四章

C++ STL String


创建

C++的基本数据类型有intboolfloatdoublecharvoid,所以string不是数据类型,而是类

int main(){
	string str;								//字符串类对象str,无初始化
	string s("123456789");					
	string str(s);							//拷贝
	string str(s,2);						//s[2...end]初始化str,str="3456789"
	string str(s,2,5);						//s[2]开始,长度为5的字符串初始化str,str="34567"
	string str(5,'c');						//用5个字符'c'初始化str
	string str(s.begin(),s.end());			//使用迭代器初始化str,str="123456789"



字符串迭代器


定义

string::iterator itr;				// itr可以读/写string对象的字符
string::const_iterator citr;		// citr只能读取string对象的字符



赋值

一般拥有迭代器的类都会同时拥有返回迭代器的成员函数。
常用的成员函数有begin()end(),前者返回指向第一个元素的迭代器,后者返回指向最后一个元素的下一个位置的迭代器,所以后者的意义主要是作为一个结束的标志,表示已经将所有的元素处理完

与上面两个相反的还有rbegin()rend(),这两个成员函数则在逻辑上从后往前看待容器,前者返回指向最后一个元素的迭代器,后者返回指向第一个元素前一个位置的迭代器


#include <iostream>
#include <string>
using namespace std;
int main(){
	string s("1,2,3,4,5");
	cout<<string(s.begin(),s.end())<<endl;
	cout<<string(s.rbegin(),s.rend())<<endl;
	
	string::iterator i;
	
	for(i = s.begin(); i!=s.end(); ++i)
		cout<<*i;
	cout<<endl;

	for(i = s.end()-1; i!=s.begin(); --i)						// A
		cout<<*i;
	cout<<*s.begin()<<endl;									// C

	string::reverse_iterator ri ;
	for(ri = s.rbegin();ri!=s.rend(); ++ri)					// B
		cout<<*ri;
}
1,2,3,4,5
5,4,3,2,1
1,2,3,4,5
5,4,3,2,1
5,4,3,2,1
  1. 迭代器通过*访问指向的地址中的内容,和指针相似
  2. 反向迭代器string::reverse_iterator ri,进行++--,行进的方向和正向迭代器相反
  3. 反向迭代器通常和rbegin()rend()匹配使用
  4. A行和B行的输出结果是一样的,但A行输出却需要补充一个C
  5. A行一开始还忘记-1




访问字符串

	string str("12345");
	char c;
	c = str[str.length()];			// 返回 '/0'
	c = str[50];					// 越界,处罚断言
	c = str.at(str.length()];		//	触发异常

修改字符串

修改assign()

	string s1("12345abcd");
	string s2;
	s2.assign(s1);							// s2 = "12345abcd"
	s2.assign(s1,4,10);						// s2 = "abcd",从下标4开始,往后取10个字符,s1长度不够则到末尾即可
	s2.assign(s1,4,s1.npos);				// s1.npos 静态常量,指向字符串的结尾处

	s2.assign(5,'X');						// s2 = "XXXXX"

	s2.assign(s1.begin(),s1.end());			
	s2.assign(s1.begin()+2, s1.end()-2);	// s2 = "345ab" 这里是减掉两个誒!!!!!

大部分都和最上边一样
但要注意最后一行,不是说end(),指向最后一个元素的下一个位置吗?
应该是自己对s2.assign(s1,4,10)的印象太过深刻,往后取字符,不够则取到末尾即可,以为迭代器也是一样的操作,这里应该是取不到迭代器指向的那个字符,所以才会有最后一行的情况


总结

如果第一个参数是字符串s1,那调用函数的s2将会被整体修改
s2.assign(s1,2,3) s2.assign(s1,0,10)
两次修改,都相当于被整体替换
如果第一个参数是数字,那第二个参数一定是字符
s2.assign(5,'X') s2 == "XXXXX"
参数还可能是两个迭代器



追加append()

	string s1("1234");
	string s2="abcd";
	
	s1.append(s2);	
	s1.append(s2,2,10);				// s1 = 1234cd, 注意第三个参数

	s1.append(s2,2);				// s1 = 1234ab
	s1.append(5,'X');				// s1 = 1234XXXXX

	s1 += "Y";						//追加单个字符,这里用的是 字符串 "Y"
	s1.append(1,'Y');
	s1.push_back('Y');

这上面的例子,每一次append()操作后,都会改变调用函数的字符串,所以注释的s1只是为了方便查看功能




插入和删除

	string s1("0123456789");
	string s2 = "abcd";

	s1.erase(7);				// s1 = 01234567 删除索引7以后的子串
	s1.erase(3,2);				// s1 = 012567
	
	s2.insert(2,s1);			// s2 = ab012567cd  在s2的索引2开始插入s1
	s2.insert(3,"广外大学");		// s2 = ab0广外大学12567cd
	cout<<s2.size();			// 18
	s2.insert(4,'Y');			// 这里乱码 s2 = ab0 *** 2567cd
	s2.insert(5,'Y');			// s2 = ab0广Y外大学12567cd

这里是因为一个中文字符占两个字节,而英文字符占一个字节,当在索引4插入一个英文字符,会打乱"广"这个字符的ASCII码,即"广"的前一个字节和Y这个字符的字节组合成一个新的两字节字符,所以出现了乱码

所以s2的索引,4个中文字符却占了8个索引,4和56和78和910和11分别是"广""外""大""学"的索引

	string s("广东外语外贸大学");
    for(char i:s) cout<<i;
    cout<<endl;
    for(int i=0;i<s.length();++i) cout<<s[i];

程序结果

骞夸笢澶栬澶栬锤澶у
骞夸笢澶栬澶栬锤澶у





替换与交换

	string s1 = "0123456";
	string s2("abcdef");
	s1.replace(2,3,s2);					// s1 = 01abcdef56
	s1.replace(2,6,s2,2,3);				// s1 = 01cde56
	s1.replace(0,5,s1,1,3);				// s1 = 1cd56
	s1.replace(1,2,5,'X');				// s1 = 1XXXXX56

	string::iterator ib = s1.begin();
	string::iterator ie = s1.end();
	s1.replace(ib+1,ie-4,s2);			// s1 = 1abcdefXX56
	s1.swap(s2);
	cout<<s1<<" "<<s2;					// s1 = abcdef	s2 = 1abcdefXX56

小小总结一下
参数如果是数字的话
一般第一个数字是要替换的字符子串的首字符下标,第二个数字是要替换的字符子串长度
参数如果是迭代器的话
第一个迭代器是要替换的子串的首字符,第二个迭代器是要替换的子串的尾字符的下一位置
也就是说替换不了第二个迭代器指向的字符

而参数如果还有一个字符串s2的话
那在s2前的数字或迭代器,操作的对象是调用该函数的字符串
s2后边的数字或迭代器,操作的对象就是s2




字符串对象上的参照

  1. 字符查找find()

参数有两个,第一个是需要查找的目标子串或字符,第二个是查找的初始位置;
若找到,返回子串第一次出现的下标,否则返回npos(串尾)
其实返回的就是整型数据,要么是某个下标要么是该字符串的length()
别忘了auto这个类型

  1. 取子串substr()

两个参数,第一个是要截取子串的首地址,第二个是要截取的长度

matrix.h: Simple matrix class dsexceptions.h: Simple exception classes Fig01_02.cpp: A simple recursive routine with a test program Fig01_03.cpp: An example of infinite recursion Fig01_04.cpp: Recursive routine to print numbers, with a test program Fig01_05.cpp: Simplest IntCell class, with a test program Fig01_06.cpp: IntCell class with a few extras, with a test program IntCell.h: IntCell class interface (Fig 1.7) IntCell.cpp: IntCell class implementation (Fig 1.8) TestIntCell.cpp: IntCell test program (Fig 1.9) (need to compile IntCell.cpp also) Fig01_10.cpp: Illustration of using the vector class Fig01_11.cpp: Dynamically allocating an IntCell object (lame) BuggyIntCell.cpp: Buggy IntCell class implementation (Figs 1.16 and 1.17) Fig01_18.cpp: IntCell class with pointers and Big Five FindMax.cpp: Function template FindMax (Figs 1.19 and 1.20) Fig01_21.cpp: MemoryCell class template without separation Fig01_25.cpp: Using function objects: Case insensitive string comparison LambdaExample.cpp: (Not in the book): rewriting Fig 1.25 with lambdas MaxSumTest.cpp: Various maximum subsequence sum algorithms Fig02_09.cpp: Test program for binary search Fig02_10.cpp: Euclid's algorithm, with a test program Fig02_11.cpp: Recursive exponentiation algorithm, with a test program RemoveEveryOtherItem.cpp: Remove every other item in a collection Vector.h: Vector class List.h: List class BinarySearchTree.h: Binary search tree TestBinarySearchTree.cpp: Test program for binary search tree AvlTree.h: AVL tree TestAvlTree.cpp: Test program for AVL trees mapDemo.cpp: Map demos WordLadder.cpp: Word Ladder Program and Word Changing Utilities SeparateChaining.h: Header file for separate chaining SeparateChaining.cpp: Implementation for separate chaining TestSeparateChaining.cpp: Test program for separate chaining hash tables (need to compile SeparateChaining.cpp also) QuadraticProbing.h: Header file for quadratic probing hash table QuadraticProbing.cpp: Implementation for quadratic probing hash table TestQuadraticProbing.cpp: Test program for quadratic probing hash tables (need to compile QuadraticProbing.cpp also) CuckooHashTable.h: Header file for cuckoo hash table CuckooHashTable.cpp: Implementation for cuckoo hash table TestCuckooHashTable.cpp: Test program for cuckoo hash tables (need to compile CuckooHashTable.cpp also) CaseInsensitiveHashTable.cpp: Case insensitive hash table from STL (Figure 5.23) BinaryHeap.h: Binary heap TestBinaryHeap.cpp: Test program for binary heaps LeftistHeap.h: Leftist heap TestLeftistHeap.cpp: Test program for leftist heaps BinomialQueue.h: Binomial queue TestBinomialQueue.cpp: Test program for binomial queues TestPQ.cpp: Priority Queue Demo Sort.h: A collection of sorting and selection routines TestSort.cpp: Test program for sorting and selection routines RadixSort.cpp: Radix sorts DisjSets.h: Header file for disjoint sets algorithms DisjSets.cpp: Efficient implementation of disjoint sets algorithm TestFastDisjSets.cpp: Test program for disjoint sets algorithm WordLadder.cpp: Word Ladder Program and Word Changing Utilities Fig10_38.cpp: Simple matrix multiplication algorithm with a test program Fig10_40.cpp: Algorithms to compute Fibonacci numbers Fig10_43.cpp: Inefficient recursive algorithm (see text) Fig10_45.cpp: Better algorithm to replace fig10_43.c (see text) Fig10_46.cpp: Dynamic programming algorithm for optimal chain matrix multiplication, with a test program Fig10_53.cpp: All-pairs algorithm, with a test program Random.h: Header file for random number class Random.cpp: Implementation for random number class TestRandom.cpp: Test program for random number class UniformRandom.h: Random number class using standard library Fig10_63.cpp: Randomized primality testing algorithm, with a test program SplayTree.h: Top-down splay tree TestSplayTree.cpp: Test program for splay trees RedBlackTree.h: Top-down red black tree TestRedBlackTree.cpp: Test program for red black trees Treap.h: Treap TestTreap.cpp: Test program for treap SuffixArray.cpp: Suffix array KdTree.cpp: Implementation and test program for k-d trees PairingHeap.h: Pairing heap TestPairingHeap.cpp: Test program for pairing heaps MemoryCell.h: MemoryCell class interface (Appendix) MemoryCell.cpp: MemoryCell class implementation (Appendix) MemoryCellExpand.cpp: MemoryCell instantiation file (Appendix) TestMemoryCell.cpp: MemoryCell test program (Appendix)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值