今日学习vector 和string容器
1、
vector容器
vector基本概念
功能:
- vector数据结构和数组非常相似,也称为单端数组
vector与普通数组区别:
- 不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展:
- 并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
- vector容器的迭代器是支持随机访问的迭代器
有关vector语法若分每一个小节来讲颇杂且短小,故放在一个大函数中,详见
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> //使用STL提供的算法
using namespace std;
void PrintVector(vector<int> v) {
//for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
// cout << *it << " ";
//}
for (int i = 0; i < v.size(); i++) {
//cout << v[i] << " ";通过数组下标访问
cout << v.at(i) << " ";//通过at()函数访问
}
cout << endl;
}
//void MyPrint(int val)
//{
// cout << val << endl;
//}
//void test01() {
// vector<int> v;
// vector<int>::iterator itbegin = v.begin();//开始迭代器,itbegin是一个指针
// vector<int>::iterator itend = v.end();//结束迭代器,vector<int>::iterator是迭代器类型
//
// v.push_back(10);
// v.push_back(20);
//第一种遍历方式
//while (itbegin != itend) {
// cout << *itbegin << endl;
// itbegin++;//++访问后面的数据
//}
第二种遍历方式
//for (vector<int>::iterator it = itbegin; it != itend; it++) {
// cout << *itbegin << endl;
//} 前两种均使用的是普通循环,通过遍历itbegin指针来寻找值,第三种方式则是自带的for_each函数,使用也方便
//第三种遍历方式
//for_each(v.begin(), v.end(),print<int>);
//}
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
};
//void test01() {
// vector<Person> v;
// vector<Person>::iterator vbegin = v.begin();
// vector<Person>::iterator vend = v.end();
//
// Person p1("a1", 10);
// Person p2("b2", 20);
// v.push_back(p1);
// v.push_back(p2);
//
// for(vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
// //cout << "name= " << it->name << " age= " << it->age << endl; //it是指向p1p2的指针,用->可取值
// //还有一种方法是解引用然后使用.name来取值
// cout << "name= " << (*it).name << " age= " << (*it).age << endl;
// }
//}
//
//void test02() {
// vector<Person*> v;
// vector<Person*>::iterator vbegin = v.begin();
// vector<Person*>::iterator vend = v.end();
//
// Person p1("a1", 10);
// Person p2("b2", 20);
// v.push_back(&p1);
// v.push_back(&p2);
//
// for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++) {
// cout << "name= " << (*it)->name << " age= " << (*it)->age << endl;
// //it是指向p1p2地址的指针,用*取到p1p2的地址,再用->取值
// }
//}
//
//void test03() {
// vector< vector<int> > v;//创建一个大容器,能够往下嵌套
// vector<int> v1;//创建一个小容器,待会插入进大容器中。
// vector<int> v2;
// vector<int> v3;
// //向小容器中插入元素
// for (int i = 0; i < 4; i++) {
// v1.push_back(10);
// v2.push_back(20);
// v3.push_back(30);
// }
// //向大容器中插入小容器
// v.push_back(v1);
// v.push_back(v2);
// v.push_back(v3);
// for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) {
// for (vector<int>::iterator vit = (*it).begin(); vit != (*it).end();vit++) {
// //(*it)解引用表示大容器指向小容器的指针
// cout << *vit <<" ";
// }
// cout << endl;//遍历完小容器之后换行
//
// }
//}
void test01()//四种构造方法
{
//1、无参构造,默认里面无值
vector<int> v1;
for (int i = 1; i <= 10; i++) {
v1.push_back(i);
}
PrintVector(v1);
//2、使用迭代器构造,以两个迭代器参数传参
vector<int> v2 (v1.begin(), v1.end());
PrintVector(v2);
//3、(n, elem)将n个elem拷贝赋值给本身。
vector<int> v3(10, 666);
PrintVector(v3);
//4、拷贝构造函数
vector<int> v4(v1);
PrintVector(v4);
}
void test02()//三种赋值方法
{
//初始化一个vector
vector<int> v1;
for (int i = 1; i <= 10; i++) {
v1.push_back(i);
}
PrintVector(v1);
//1、直接等号赋值
vector<int> v2 = v1;
PrintVector(v2);
//2、assign(n, elem); //将n个elem拷贝赋值给本身。
vector<int> v3;
v3.assign(10, 555);
PrintVector(v3);
//3、迭代器赋值
vector<int> v4;
v4.assign(v1.begin(), v1.end());
PrintVector(v4);
}
void PrintSize(vector<int> &v) {
cout << "容器容量为:" << v.capacity() << endl;
cout << "容器大小为:" << v.size() << endl;
}
void test03() {//容器的大小和容量以及判断是否为空
//初始化一个vector
vector<int> v1;
for (int i = 1; i <= 10; i++) {
v1.push_back(i);
}
PrintVector(v1);
//v1.resize(0);若直接将大小设为0,会判断为空
//if判断是否空
if (v1.empty()) {
cout << "当前容器为空" << endl;
}
else {
cout << "当前容器不为空" << endl;
}
//输出容器和大小
PrintSize(v1);
//v1.resize(20);//重新定义容器大小,默认用0补齐
//PrintVector(v1);
//PrintSize(v1);
v1.resize(5);//减少容器大小,会发现vector容器不会动态收缩,容量仍是最大的13
PrintVector(v1);
PrintSize(v1);
vector<int>(v1).swap(v1);//匿名对象执行完当前行就释放,这里实际上使用了一个匿名函数与v1进行交换,v1得到的就是刚好符合他大小的容量,匿名对象换到的则是v1原来的容量,但是执行完当前行就被释放了,也没关系。
//总结:可以利用swap函数进行内存的收缩
PrintVector(v1);
PrintSize(v1);
}
void test04() {//插入删除操作
//初始化一个vector
vector<int> v1;
for (int i = 1; i <= 10; i++) {
v1.push_back(i);//尾插数据
}
PrintVector(v1);
v1.pop_back();//尾删数据
PrintVector(v1);
PrintSize(v1);
v1.insert(v1.end(),10);//在迭代器的位置插入数据
PrintVector(v1);
PrintSize(v1);
v1.erase(v1.begin());//在迭代器的位置删除数据
PrintVector(v1);
PrintSize(v1);
//v1.erase(v1.begin(),v1.end());
//PrintVector(v1);
//PrintSize(v1);
vector<int>::iterator it = v1.begin();
cout << *it <<v1.front()<<v1.back();
//v1.front()访问第一个元素,v1.back()访问最后一个元素
}
void test05() {
vector<int> v1;
int* p = NULL;
int num=0;
v1.reserve(100);
for (int i = 1; i <= 100; i++) {
v1.push_back(i);//尾插数据
if (p != &v1[0]) {//因为v1每次动态拓展会开辟新内存,所以用p指针的判断统计v1有没有开辟新内存。
p = &v1[0];
num++;
}
}
cout << num << endl;
PrintVector(v1);
}
int main() {
test05();
return 0;
}
还有要补充几点:vector<int> v (100)就是指创建一个大小为100的容器,与数组定义类似
2、string容器
string基本概念
本质:
- string是C++风格的字符串,而string本质上是一个类
string和char * 区别:
- char * 是一个指针
- string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器。
特点:
string 类内部封装了很多成员方法
例如:查找find,拷贝copy,删除delete 替换replace,插入insert
string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
3.1.2 string构造函数
构造函数原型:
string();
//创建一个空的字符串 例如: string str;string(const char* s);
//使用字符串s初始化string(const string& str);
//使用一个string对象初始化另一个string对象string(int n, char c);
//使用n个字符c初始化
#include <iostream>
#include <string> //使用string容器
#include <vector>
#include <algorithm> //使用STL提供的算法
using namespace std;
void test01() {//四种构造方法
string s1;//空构造
cout << "s1= " << s1 << endl;
const char* p = "Hello World!";
//cout << "p= " << p << " *p=" << *p << endl;
//可以发现p指向的是字符数组"Hello World!",*p指向的是H首元素
string s2(p);
cout << "s2= " << s2 << endl;
string s3(s2);//拷贝构造
cout << "s3= " << s3 << endl;
string s4(10, 'c');//使用n个字符初始化,若传入多个字符只会识别最后一个,'abc'->'c'
cout << "s4= " << s4 << endl;
}
void test02() {
string s1 = "hello";
cout << "s1= " << s1 << endl;
string s2 = s1;
cout << "s2= " << s2 << endl;
string s3;
s3 = 'a';
cout << "s3= " << s3 << endl;
string s4;
s4.assign("hello world");
cout << "s4= " << s4 << endl;
string s5;
s5.assign("hello world", 7);
cout << "s5= " << s5 << endl;
string s6;
s6.assign(s5);
cout << "s6= " << s6 << endl;
string s7;
s7.assign(7, 's');
cout << "s7= " << s7 << endl;
}
void test03() {
string s1 = "hello";
s1 += "world";
cout << "s1= " << s1 << endl;
string s2 = "friend";
s2 += s1;
cout << "s2= " << s2 << endl;
string s3 = s1;
s3.append("C++");//在末尾添加字符
cout << "s3= " << s3 << endl;
s3.append(s2, 4);//从第四个位置添加字符串
cout << "s3= " << s3 << endl;
s3.append(s2, 1, 4);//截取第1到4个字符
cout << "s3= " << s3 << endl;
}
void test04() {
string s1 = "hello world";
int pos = s1.find('l');
if (pos == -1)
{
cout << "未找到" << endl;
}
else
{
cout << "pos = " << pos << endl;
}
cout << "-------------" << endl;
pos = s1.rfind('l');
if (pos == -1)
{
cout << "未找到" << endl;
}
else
{
cout << "pos = " << pos << endl;
}
s1.replace(2, 5, "aaaaaaaa");//从第二个开始,替换五个字符
cout << "s1=" << s1 << endl;
}
void test05()
{
string s1 = "hello";
string s2 = "hello";
int ret = s1.compare(s2);
if (ret == 0) {
cout << "s1 等于 s2" << endl;
}
else if (ret > 0)//比较ASCII码大小,大于返回值1大于零,小于返回值-1小于零
{
cout << "s1 大于 s2" << endl;
}
else
{
cout << "s1 小于 s2" << endl;
}
}
void test06() {//字符的读取和存取
string s = "hello";
for (int i = 0; i < s.size(); i++) {
//cout << s[i] << " ";
cout << s.at(i) << " ";//与vector类似,可以通过[]和at()访问
}
cout << endl;
s[0] = 'x';
s.at(1) = 'x';
for (int i = 0; i < s.size(); i++) {
cout << s[i] << " ";
//cout << s.at(i) << " ";
}
cout << endl;
}
void test07()
{
string str = "hello";
str.insert(1,"999");
cout << str << endl;
//从1号位置开始4个字符
str.erase(1, 4);
cout << str << endl;
}
void test08() {
string str = "lisi@QQ.com";
string strson = str.substr(1, 4);
cout << "strson = " << strson << endl;
int pos = str.find("@");//通过find函数找到@的位置,从零到pos的位置就是几个 字符
string username = str.substr(0, pos);
cout << "username = " << username << endl;
}
int main() {
//test01();
test08();
return 0;
}