c++ primer第五版----学习笔记(九)

1.顺序容器概述

  • 顺序容器类型:
vector                 //可变大小数组,支持快速随机访问,在尾部之外的位置插入或删除元素很慢
deque                  //双端队列,支持快速随机访问,在头尾位置插入或删除元素很快
list                   //双向链表,支持双向顺序访问,在list任何位置插入或删除元素都很快
forward_list           //单向链表,只支持单向顺序访问,在任何位置插入或删除元素都很快
array                  //固定大小数组,支持快速随机访问,不能添加或删除元素
string                 //与vector类似

//list与forward_list不支持元素的随机访问

  • 确定使用哪种容器类型:一般来说使用vector(其他情况看程序具体要求)

2.容器库概览

  • 迭代器:
//迭代器类型
iterator
const_iterator    //可以读,但不能修改
//迭代器范围:[begin,end),左闭合区间
  • begin和end成员:
//begin和end有多个版本,带r的返回反向迭代器;带c的返回const迭代器
list<string> a = {"kl", "ju", "ku"};
auto it1 = a.rbegin();   //list<string>::reverse_iterator
auto it2 = a.cbegin();   //list<string>::const_iterator
auto it3 = a.crbegin();  //list<string>::const_reverse_iterator
  • 容器定义和初始化:
/*将一个容器初始化未另一个容器的拷贝:直接拷贝整个容器;拷贝由一个迭代器对指定的范围
1.当将一个容器初始化为另一个容器的拷贝时,必须要求容器类型与元素类型都相同
2.当传递迭代器来拷贝时,不要求容器类型相同,而且,元素类型也可以不同,只是要求能够转换
*/
vector<const char*> articles = {"a","an","the"};
//正确:可以将const char*元素转换为string
forward_list<string> words(articles.begin(), articles.end());

//当定义一个array时,除了指定元素类型,还要指定容器大小
array<int, 42>;
array<int>::size_type j;      //错误:array<int>不是一个类型(使用array时也必须指定大小)
  • 赋值操作:
//赋值运算
swap(c1, c2);         //交换c1和c2中的元素,c1和c2的类型必须相同       
c1.swap(c2);

//assign操作不适用于关联容器和array
seq.assign(b, e);        //将seq中的元素替换为迭代器b和e所表示范围中的元素
seq.assign(il);          //将seq中的元素替换为初始化列表il中的元素
seq.assign(n,t);         //将seq中的元素替换为n个值为t的元素
//赋值相关运算会导致指向容器内部的迭代器、引用和指针失效;swap不会(容器类型为array和string的除外)

/*使用swap

1.对于除array外的所有容器使用swap,都不会使两个容器的元素交换,仅仅交换两个容器的内部数据结构
2.对于array使用swap,会真正交换它们的元素,但指针、引用和迭代器所绑定的元素不变
  • 只有当其元素类型定义了相应的比较运算符时,我们才可以使用关系运算符来比较两个容器

3.顺序容器操作

  • 向顺序容器添加元素:
/*forward_list有自己专有版本的insert和emplace
forward_list不支持push_back和emplace_back
vector和string不支持push_front和emplace_front
*/
c.push_back(t)                 //在c的尾部创建一个值为t或由args创建的元素
c.emplace_back(args)

c.push_front(t)                //在c的头部创建一个值为t或由args创建的元素
c.emplace_front(args)

c.insert(p,t)                  //在迭代器p指向的元素之前创建一个值为t或由args创建的元素
c.emplace(p,args)
c.insert(p,n,t)                //在迭代器p指向的元素之前插入n个值为t的元素
c.insert(p,b,e)                //在迭代器p指向的元素之前插入迭代器b和e指定的范围内的元素
c.insert(p,il)                 //在迭代器p指向的元素之前元素值列表il中的值

//向一个vector、string或deque插入元素会使所有指向容器的迭代器、引用和指针失效

//注意:当向容器中插入元素时,注意迭代器可能失效,所有需要重新指定迭代器

//理解下面的程序:使用insert的返回值
list<string> lst;
auto iter = lst.begin();
while (cin >> word)
    iter = lsts.insert(iter, word);         //等价于调用push_front

//1.当我们调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中
//2.而当我们调用emplace时,则是将参数传递给元素类型的构造函数
  • 访问元素:
//at和下标操作只适用于string、vector、deque和array
//back不适用于forward_list
c.back()             //返回c中尾元素的引用
c.front()            //返回c中首元素的引用
c[n]                 //返回c中下标为n的元素的引用
c.at(n)              //返回下标为n的元素的引用

//对一个空容器调用back和front,是一个严重的程序设计错误

if (!c.empty())
{
    c.front() = 42;
    auto &v = c.back();      //获得指向最后一个元素的引用
    v = 1024;                //改变c中的元素
    auto v2 = c.back();      //v2不是一个引用,它是c中最后一个元素的拷贝
    v2 = 0;                  //c中元素不改变
}
  • 删除元素:
/*删除元素改变容器大小,不适用于array
forward_list有特殊版本的erase
forward_list不支持pop_back;vector和string不支持pop_front
*/

c.pop_back()             //删除c中尾元素
c.pop_front()            //删除c中首元素
c.erase(p)               //删除迭代器p所指向的元素,返回一个指向被删元素之后元素的迭代器
c.erase(b,e)             //删除迭代器b和e所指定范围内的元素,返回一个指向最后一个被删元素之后元素的迭代器
c.clear()                //删除c中所有元素

//1.删除deque中除首尾位置之外的任何元素都会使所有迭代器、引用和指针失效
//2.指向vector或string中删除点之后位置的迭代器、引用和指针都会失效
  •  特殊的forward_list操作:
//在forward_list中插入或删除元素的操作
lst.before_begin()         //返回指向链表首元素之前不存在的元素的迭代器
lst.cbefore_begin()        //.......cbefore_begin()返回一个const_iterator

lst.insert_after(p,t)      //在迭代器p之后的位置插入元素,t是一个对象,n是数量,b和e是
lst.insert_after(p,n,t)    //表示范围的一对迭代器,il是一个元素值列表
lst.insert_after(p,b,e)
lst.insert_after(p,il)

emplace_after(p,args)      //使用args在p指定的位置之后创建一个元素,返回一个指向这个新元素的迭代器

lst.erase_after(p)         //删除p指向的位置之后的元素,或删除从b之后到e之间的元素
lst.erase_after(b,e)       //返回一个指向被删元素之后元素的迭代器
  • 改变容器大小:
//resize不适用于array
c.resize(n)         //调整c的大小为n个元素,若n<c.size(),则多出的元素被丢弃;否则新元素被初始化
c.resize(n,t)       //调整c的大小为n,任何新添加的元素被初始化为t

//1.如果resize缩小容器,则指向被删除元素的迭代器、引用和指针都会失效
//2.对vector、string或deque进行resize可能导致迭代器、引用和指针失效

4.管理容量的成员函数

//shrink_to_fit只适用于vector、string和deque
//capacity和reserve只适用于vector和string
c.shrink_to_fit()    //请将capacity()减少为与size()相同大小
c.capacity()         //不重新分配内存空间的话,c可以保存多少元素
c.reserve(n)          //分配至少能容纳n个元素的内存空间

//reserve并不改变容器中元素的数量,它仅影响vector预先分配多大的内存空间

5.额外的string操作

  • 构造string:
//
string s(cp,n)             //s是cp指向的数组中前n个字符的拷贝
string s(s2,pos2)          //s是string s2从下标pos2开始的字符的拷贝
string s(s2,pos2,len2)     //s是string s2从下标pos2开始len2个字符的拷贝

//substr操作
s.substr(pos,n)            //返回一个string,包含s中从pos开始的n个字符的拷贝;pos默认值为0
  • 改变string:
s.insert(pos,args)           //在pos之前插入args指定的字符;接受下标的版本返回一个指向s的引用
                             //接受迭代器版本返回一个指向第一个插入字符的迭代器
s.erase(pos,len)             //删除从位置pos开始的len个字符,返回一个指向s的引用

s.assign(args)               //将s中的字符替换为args指定的字符,返回一个指向s的引用

s.append(args)               //将args追加到s,返回一个指向s的引用

s.replace(range,args)        //删除s中范围range内的字符,替换为args指定的字符
  • string搜索操作:
//搜索操作返回制定字符出现的下标,若未找到则返回npos
s.find(args)                        //查找s中args第一次出现的位置
s.rfind(args)                       //查找s中args最后一次出现的位置
s.find_first_of(args)               //在s中查找args中任何一个字符第一次出现的位置
s.find_last_of(args)                //在s中查找args中任何一个字符最后一次出现的位置
s.find_first_not_of(args)           //在s中查找第一个不在args中的字符
s.find_last_not_of(args)            //在s中查找最后一个不在args中的字符
  • 数值转换:
to_string(val)       //返回数值val的string表示,val可以是任何算术类型

stoi(s,p,b)          //返回值类型分别是int、long、unsigned long、long long、unsigned long long
stol(s,p,b) 
stoul(s,p,b)
stoll(s,p,b)
stoull(s,p,b)

stof(s,p)             //返回值类型分别是float、double、long double
stod(s,p)
stold(s,p)

6.容器适配器(stack、queue、priority_queue):

适配器:一个适配器是一种机制,能使某种事物的行为看起来向另外一种事物一样

  • 栈适配器:
s.pop()                   //删除栈顶元素,但不返回该元素值
s.push(item)              //创建一个新元素压入栈顶,该元素通过拷贝或移动item而来,或由args构造
s.emplace(args)
s.top()                   //返回栈顶元素,但不将元素弹出栈
  • 队列适配器:
//queue默认基于deque实现,priority_queue默认基于vector实现
q.pop()                    //删除queue中首元素或priority_queue中最高优先级元素
q.front()                  //返回首元素或尾元素,其中back只适用于queue
q.back()
q.top()                    //返回最高优先级元素,只适用于priority_queue
q.push(item)               //在queue末尾或priority_queue中恰当位置创建一个元素
q.emplace(args)

7.部分习题解答

9.4、9.5:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;

bool  find_1(vector<int>::iterator x, vector<int>::iterator y, int n)
{
	for (x; x != y; ++x)
	{
		if (*x == n)
		{
			return true;        //第5题改为return a;
		}
	}
	return false;               //第5题改为return b;
}

int main(int argc,char **argv)
{
	vector<int> vec{ 1,2,3,4,5,6,7,8,9 };
	int find_number = 4;
	if (find_1(vec.begin(), vec.end(), find_number))     //第5题改为!= vec.end();
	{
		cout << "find it" << endl;
	}
	else
	{
		cout << "can't fint it" << endl;  
	}
	system("pause");
    return 0;
}

9.6:

链表容器实现了比较运算符,只是在定义链表的iterator类时没有对operator进行重载

9.10:

it1:    vector<int>::iterator

it2:    vector<int>::const_iterator

it3:    vector<int>::const_iterator

it4:    vector<int>::const_iterator

9.11:

vector<int> vec;
vector<int> vec(10);
vector<int> vec(10,1);
vector<int> vec{1,2,3,4,5};
vector<int> vec(vec1);
vector<int> vec(vec1.begin(),vec1.end());

9.12:

接受一个容器拷贝,就是拷贝整个容器的内容;接受迭代器拷贝,拷贝的是两迭代器之间的内容

9.13:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
using namespace std;

int main(int argc,char **argv)
{
	//使用列表初始化创建目标容器
	list<int> list1{ 1,2,3,4,5 };
	vector<int> vec1{ 6,7,8,9,10 };
	
	//使用迭代器拷贝两个容器的内容
	vector<double> vec2(list1.begin(), list1.end());
	vector<double> vec3(vec1.begin(), vec1.end());

	//验证正确性
	for (auto &c : vec2)
	{
		cout << c << endl;
	}
	for (auto &c : vec3)
	{
		cout << c << endl;
	}
	system("pause");
        return 0;
}

9.14:

list<char *> lst;
vector<string> vec;
vec.assign(lst.begin(),lst.end());

9.15:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
using namespace std;

int main(int argc,char **argv)
{
	//创建两个需要比较的容器
	vector<int> vec1{ 1,2,3,4,5 };
	vector<int> vec2{ 1,2,3,4,5 };

	//判断
	int flag = 0;
	if (vec1.size() == vec2.size())
	{
		for (auto beg1 = vec1.begin(), beg2 = vec2.begin(); beg1 != vec1.end(); ++beg1, ++beg2)
		{
			if (*beg1 != *beg2)
			{
				flag = 1;
			}
		}
		if (flag == 1)
		{
			cout << "两vector<int>不相等!" << endl;
		}
		else {
			cout << "两vector<int>相等!" << endl;
		}
	}
	else
	{
		cout << "两vector<int>不相等!" << endl;
	}
	system("pause");
        return 0;
}

9.16:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
using namespace std;

int main(int argc,char **argv)
{
	//创建两个需要比较的容器
	vector<int> vec1{ 1,2,3,4,5 };
	list<int> list1{ 1,2,3,4,5 };

	//判断
	int flag = 0;
	if (vec1.size() == list1.size())
	{
		auto beg2 = list1.begin();
		for (auto beg1 = vec1.begin(); beg1 != vec1.end(); ++beg1, ++beg2)
		{
			if (*beg1 != *beg2)
			{
				flag = 1;
			}
		}
		if (flag == 1)
		{
			cout << "两容器元素不相等!" << endl;
		}
		else {
			cout << "两容器元素相等!" << endl;
		}
	}
	else
	{
		cout << "两容器元素不相等!" << endl;
	}
	system("pause");
        return 0;
}

9.17:

容器类型必须相同,元素类型也必须相同,其次元素类型必须支持 < 运算符

9.18:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
using namespace std;

int main(int argc,char **argv)
{
	string str;
	deque<string> deq;
	while (cin >> str)
	{
		deq.push_back(str);
	}
	for (auto it = deq.begin(); it != deq.end(); ++it)
	{
		cout << *it << endl;
	}
	system("pause");
        return 0;
}

9.19:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
using namespace std;

int main(int argc,char **argv)
{
	string str;
	list<string> list1;
	while (cin >> str)
	{
		list1.push_back(str);
	}
	for (auto it = list1.begin(); it != list1.end(); ++it)
	{
		cout << *it << endl;
	}
	system("pause");
        return 0;
}

9.20:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
using namespace std;

int main(int argc,char **argv)
{
	int n;
	list<int> list1;
	deque<int> deq1;
	deque<int> deq2;
	while (cin >> n)
	{
		list1.push_back(n);
	}
	for (auto it = list1.begin(); it != list1.end(); ++it)
	{
		if (*it % 2 == 0)
		{
			deq1.push_back(*it);
		}
		else
		{
			deq2.push_back(*it);
		}
	}
	cout << "偶数为:";
	for (auto it = deq1.begin(); it != deq1.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl << "奇数为:";
	for (auto it = deq2.begin(); it != deq2.end(); ++it)
	{
		cout << *it << " ";
	}
	system("pause");
        return 0;
}

9.22:循环中未对iter进行递增操作,iter无法向中点推进,其次,即使加入了++iter语句,由于向iv中插入了元素后,iter已经失效,++iter也不可能起到将迭代器向前推进的作用(我个人的看法是找到那个指定的元素然后在容器首位置插入该元素值得2倍)

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
using namespace std;

int main(int argc, char **argv)
{
	int some_val = 2,i =1;
	vector<int> iv{ 1,2,2,2,2,3,4,4,5,6,7};
	vector<int>::iterator iter = iv.begin(),
	mid = iv.begin() + iv.size() / 2;
	while (iter < mid)                                  //由于下面if操作可能使iter越过mid,所以改为小于mid
	{
		if (*iter == some_val)
		{
			iter = iv.begin();                          //插入位置重新确定
			iter = iv.insert(iter, 2 * some_val);       //插入相等值的两倍,并使iter指向容器首元素
			mid = iv.begin() + iv.size() / 2;           //由于插入操作使得mid无效,需重新定义
			iter = iter + 2 * i;                        //使iter指向原容器的下一个元素
			++i;
		}
		else
		{
			++iter;                                    //若元素值不相等,则使iter指向容器的下一元素
		}
	}
	for (iter = iv.begin(); iter != iv.end(); ++iter)
	{
		cout << *iter << " ";
	}
	system("pause");
        return 0;
}

9.24:

vector<int> vec;             //vec不为空
int a = vec.front(); 
int b = vec[0];
int c = vec.at[0];
int d = *vec.begin();

9.26:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
using namespace std;

int main(int argc, char **argv)
{
	int ia[] = { 0, 1,1,2,3,5,8,13,21,55,89 };
	vector<int> vec(ia, ia + 11);
	list<int> list1(ia, ia + 11);
	vector<int>::iterator it = vec.begin();
	list<int>::iterator it1 = list1.begin();
	while (it != vec.end())
	{
		if (*it % 2 == 0)
		{
			it = vec.erase(it);
		}
		else
		{
			++it;
		}
	}
	while (it1 != list1.end())
	{
		if (*it1 % 2 != 0)
		{
			it1 = list1.erase(it1);
		}
		else
		{
			++it1;
		}
	}
	//注意使用erase删除元素之后迭代器会失效,因此需重新定义迭代器
	for (auto it2 = vec.begin(); it2 != vec.end(); ++it2)
	{
		cout << *it2 << " ";
	}
	cout << endl;
	for (auto it3 = list1.begin(); it3 != list1.end(); ++it3)
	{
		cout << *it3 << " ";
	}
	system("pause");
        return 0;
}

9.27:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	forward_list<int> flst = { 0,1,2,3,4,5,6,7,8,9 };
	auto prev = flst.before_begin();          //表示首前元素
	auto curr = flst.begin();                 //表示flst中的第一个元素
	while (curr != flst.end())                //仍有元素要处理
	{ 
		if (*curr % 2 != 0)
		{
			curr = flst.erase_after(prev);    //删除它并移动它
		}
		else
		{
			prev = curr;                    //移动迭代器curr,指向下一个元素,prev指向curr之前元素
			++curr;
		}
	}
	auto it = flst.begin();
	for (; it != flst.end(); ++it)
	{
		cout << *it << " ";
	}
	system("pause");
        return 0;
}

9.28:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

void insert(forward_list<string> &flst, string str1, string str2)  //要对容器中的元素做修改,注意使用引用
{
	int flag = 0;
	auto prev = flst.before_begin();
	auto it = flst.begin();
	for (; it != flst.end(); prev = it++)
	{
		if (*it == str1)
		{
			flag = 1;
			flst.insert_after(it,str2);
		}
	}
	if (flag == 0)
	{
		flst.insert_after(prev,str2);
	}
}
int main(int argc, char **argv)
{
	forward_list<string> flst;
	string str, str1, str2;
	auto it = flst.before_begin();
	while (cin >> str)
	{
		it = flst.insert_after(it, str);
	}
	cin.clear();
	cin >> str1 >> str2;
	insert(flst, str1, str2);
	for (auto it = flst.begin();it!=flst.end();++it)
	{
		cout << *it << endl;
	}
	system("pause");
        return 0;
}

9.30:

对于元素是类类型,则要求该类必须提供一个默认构造函数

9.31:

forward_list、list的迭代器不支持加减运算,因为双向链表和单向链表存储元素都不在一个连续的内存上

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	list<int> lst{ 0,1,2,3,4,5,6,7,8,9 };
	forward_list<int> fst{ 0,1,2,3,4,5,6,7,8,9 };
	cout << "before list: ";
	for (auto c : lst)
		cout << c << " ";
	cout << endl;
	auto iter1 = lst.begin();
	while (iter1 != lst.end())
	{
		if (*iter1 % 2)
		{
			iter1 = lst.insert(iter1, *iter1);
			++iter1;                            //由于list与forward_list迭代器不支持加减运算符
			++iter1;                            //多次使用++运算符使迭代器指向下一个元素
		}
		else
		{
			iter1 = lst.erase(iter1);
		}
	}
	cout << "now list: ";
	for (auto c : lst)
		cout << c << " ";

	cout << endl << "before forward_list: ";
	for (auto c : fst)
		cout << c << " ";
	auto prev = fst.before_begin();
	auto iter2 = fst.begin();
	while (iter2 != fst.end())
	{
		if (*iter2 % 2)
		{
			iter2 = fst.insert_after(iter2, *iter2);
			prev = iter2;
			++iter2;
		}
		else
		{
			iter2 = fst.erase_after(prev);
		}
	}
	cout<<endl << "now forward_list: ";
	for (auto c : fst)
		cout << c << " ";
	system("pause");
        return 0;
}

9.32:

不合法,编译器在编译代码时,首先对*iter++求值,传递给insert第二个形参,此时iter已指向当前奇数的下一个元素,因此传递给insert的第一个参数是错误位置,程序执行会发生混乱

9.38:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	vector<int> vec;
	int n;
	while (cin >> n)
	{
		vec.push_back(n);
		cout << "vector的大小为:" << vec.size() << endl;
		cout << "vector的容量为:" << vec.capacity() << endl;
	}
	system("pause");
    return 0;
}
9.39、9.40:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

void func(int val)
{
	vector<string> svec;
	svec.reserve(1024);
	string word = "mystring";
	for (int i = 0; i < val; ++i)
	{
		svec.push_back(word);
	}
	svec.resize(svec.size() + svec.size() / 2);
	cout << "输入" << val << "个词后size" << svec.size() << endl;
	cout << "输入" << val << "个词后capacity" << svec.capacity() << endl;
}
int main(int argc, char **argv)
{
	func(256);
	func(512);
	func(1024);
	func(2048);
	system("pause");
        return 0;
}

9.41:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	vector<char> vec{ 'b','e','a','u','t','i','f','u','l' };
	string my_string(vec.data(), vec.size());
	cout << my_string << endl;
	system("pause");
        return 0;
}

9.42:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;
void inputstring(string &str)
{
	str.reserve(100);
	char c;
	while (cin >> c)
	{
		str.push_back(c);
	}
}
int main(int argc, char **argv)
{
	string str;
	inputstring(str);
	cout << str << endl;
	system("pause");
        return 0;
}

9.43:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

void replace(string &s, string oldVal, string newVal)
{
	if (s.empty() || oldVal.empty())      //判断字符串是否为空,若为空则结束程序
		return;
	if (s.size() < oldVal.size())         //如果s的长度小于要替换的字符串长度则结束程序
		return;
	auto sIter = s.begin();
	auto oldIter = oldVal.begin();
	while (sIter != s.end())
	{
		if (*sIter == *oldIter && oldIter!=oldVal.end())  //如果要替换的字符串的字符与s中字符匹配,则继续比较
			++oldIter;
		else
			oldIter = oldVal.begin();                    //否则从头比较

		++sIter;
		
		if (oldIter == oldVal.end())
		{
			oldIter = oldVal.begin();
			sIter = s.erase(sIter - oldVal.size(), sIter);  //删除s中要被替换的字符
			for (string::size_type index = 0; index < newVal.size(); ++index)   //将替换的字符串插入s中
			{
				sIter = s.insert(sIter, newVal[index]);        //sIter指向插入的字符
				++sIter;                                 //将sIter指向插入字符的下一个位置
			}
		}
	}
	
}
int main(int argc, char **argv)
{
	string mystring = "a an tho thu thru";
	replace(mystring, "tho", "though");
	cout << "替换后的mystring为:" << mystring << endl;
	replace(mystring, "thru", "through");
	cout << "替换后的mystring为:" << mystring << endl;
	system("pause");
        return 0;
}

9.44:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

void replace(string &s, string oldVal, string newVal)
{
	if (s.empty() || oldVal.empty())      //判断字符串是否为空,若为空则结束程序
		return;
	if (s.size() < oldVal.size())         //如果s的长度小于要替换的字符串长度则结束程序
		return;
	string::size_type sIndex = 0;
	string::size_type oldIndex = 0;
	while (sIndex!=s.size())
	{
		if (s[sIndex]==oldVal[oldIndex] && oldIndex!=oldVal.size())  //如果要替换的字符串的字符与s中字符匹配,则继续比较
			++oldIndex;
		else
			oldIndex = 0;                    //否则从头比较

		++sIndex;
	if (oldIndex == oldVal.size())
		{
			oldIndex = 0;
			s.replace(sIndex - oldVal.size(), oldVal.size(), newVal);
			sIndex += newVal.size() - oldVal.size();   //将sIndex置为替换字符串后最后一个字符位置
		}
	}
}
int main(int argc, char **argv)
{
	string mystring = "a an tho thu thru";
	replace(mystring, "tho", "though");
	cout << "替换后的mystring为:" << mystring << endl;
	replace(mystring, "thru", "through");
	cout << "替换后的mystring为:" << mystring << endl;
	system("pause");
        return 0;
}

9.45:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

void func(string &s, string before, string after)
{
	s.insert(s.begin(), before.begin(),before.end());
	s.append(after);
}
int main(int argc, char **argv)
{
	string s("Jhon ");
	func(s, "Mr.", "Jr.");
	cout << s << endl;
	system("pause");
        return 0;
}

9.46:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

void func(string &s, string before, string after)
{
	s.insert(s.begin(), before.begin(), before.end());
	s.insert(s.end(), after.begin(), after.end());
}
int main(int argc, char **argv)
{
	string s("Jhon ");
	func(s, "Mr.", "Jr.");
	cout << s << endl;
	system("pause");
        return 0;
}

9.47:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	string str = "ab2c3d7R4E6";
	string num = "0123456789";

	string::size_type pos = 0;
	while ((pos = str.find_first_of(num, pos)) != string::npos)
	{
		cout << str[pos] << " ";
		++pos;
	}
	cout << endl;
	string::size_type pos1 = 0;
	while ((pos1 = str.find_first_not_of(num, pos1)) != string::npos)
	{
		cout << str[pos1] << " ";
		++pos1;
	}
	system("pause");
        return 0;
}

9.49:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	string not_str = "bdfghjklpqty";
	string mystring, p_string;
	string::size_type len = p_string.size();
	ifstream in("file.txt");
	if (in)
	{
		while (in >> mystring)      //从文件中读取字符串
		{
			string::size_type pos = 0;
			if ((pos = mystring.find_first_of(not_str, pos)) == string::npos)  //如果字符串中不包含上述字符则进入
			{
				if (mystring.size() > len)
				{
					p_string = mystring;
				}
			}
		}
	}
	cout << p_string << endl;
	system("pause");
        return 0;
}

9.50:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

int main(int argc, char **argv)
{
	vector<string> vec ;
	string word;
	int sum1 = 0;
	double sum2 = 0.0;
	while (cin >> word)
	{
		vec.push_back(word);
	}
	for (auto it = vec.begin(); it != vec.end(); ++it)
	{
		sum1 += stoi(*it);
		sum2 += stod(*it);
	}
	cout << "int和为:" << sum1 << endl;
	cout << "double和为:" << sum2 << endl;
	system("pause");
        return 0;
}

9.51:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <list>
#include <deque>
#include <forward_list>
using namespace std;

class Date
{
public:
	unsigned year, month, day;
	void show_date();
	Date(string);
};

Date::Date(string s)
{
	int flag = 0;                     //区分哪种格式的日期输入
	string num = "0123456789/";       //用来判断输入日期是1/1/1990这种格式
	string douhao = ",";   //用来判断输入日期是January 1,1990这种格式
	string _month;
	unsigned pos, pos1, pos2, pos3, _pos, _pos1;
	unsigned n = 1;
	if ((pos = s.find_first_not_of(num)) == string::npos)
	{
		flag = 1;
	}
	if ((pos = s.find_first_of(douhao)) != string::npos)
	{
		flag = 2;
	}
	switch (flag)
	{
	case 1:                     //处理1/1/1990格式
		pos1 = 0;
		pos1 = s.find_first_of("/", pos1);
		day = stoul(s.substr(0, pos1));
		pos2 = ++pos1;
		pos1 = s.find_first_of("/", pos1);
		month = stoul(s.substr(pos2, pos1));
		pos3 = ++pos1;
		year = stoul(s.substr(pos3, s.size() - 1));
		break;
	case 2:                    //处理January 1,1990格式
		_pos;
		_pos = s.find_first_of(num);
		_month = s.substr(0, _pos);
		if (_month == "January ") month = 1;
		else if (_month == "February ") month = 2;
		else if (_month == "March ") month = 3;
		else if (_month == "April ") month = 4;
		else if (_month == "May ") month = 5;
		else if (_month == "June ") month = 6;
		else if (_month == "July ") month = 7;
		else if (_month == "August ") month = 8;
		else if (_month == "September ") month = 9;
		else if (_month == "October ") month = 10;
		else if (_month == "November ") month = 11;
		else if (_month == "December ") month = 12;
		else
			cerr << "wrong format: ";
		_pos1 = ++_pos;
		_pos = s.find_first_of(",", _pos);
		day = stoul(s.substr(_pos1 - 1, _pos));

		year = stoul(s.substr(_pos + 1, s.size() - 1));
		break;
	case 0:                     //处理Jan 1 2012格式
		_pos;
		_pos = s.find_first_of(num);
		_month = s.substr(0, _pos);
		if (_month == "Jan ") month = 1;
		else if (_month == "Feb ") month = 2;
		else if (_month == "Mar ") month = 3;
		else if (_month == "Apr ") month = 4;
		else if (_month == "May ") month = 5;
		else if (_month == "Jun ") month = 6;
		else if (_month == "Jul ") month = 7;
		else if (_month == "Aug ") month = 8;
		else if (_month == "Sep ") month = 9;
		else if (_month == "Oct ") month = 10;
		else if (_month == "Nov ") month = 11;
		else if (_month == "Dec ") month = 12;
		else  cerr << "wrong format: " << endl;
		_pos1 = ++_pos;
		_pos = s.find_first_of(" ", _pos);
		day = stoul(s.substr(_pos1 - 1 , _pos));

		year = stoul(s.substr(_pos, s.size() - 1));
		break;
	}

}
void Date::show_date()
{
	cout << year << "年" << month << "月" << day << "日" << endl;
}
int main(int argc, char **argv)
{
	Date date1("January 10,2012");
	date1.show_date();
	Date date2("10/10/2017");
	date2.show_date();
	Date date3("Jan 12 2018");
	date3.show_date();
	system("pause");
        return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值