⭐️STL⭐️之string和vector全解,❤️算法必备❤️<上>

简介: ⭐️STL⭐️之string和vector全解,❤️算法必备❤️<上>

前言

码神本来是想一次性就把STL,都讲完的,但是上次爆肝5w字后发现效果并不好,所以就把STL拆分成了,三个小部分来讲解,感觉还是比较重要的,算法也在继续,但是我感觉干算法以前还是要讲一下——STL,所以发车了,去做自己喜欢的事情吧!
🎉欢迎关注🔎点赞👍收藏⭐️留言📝

STL的组成

何为STL,在书中是这样描述的:C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了💕通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量、链表、队列、栈。
如果说他的存在是为了什么的话,我想应该是提高了可重复利用性。
核心:

  • 容器
  • 迭代器
  • 算法

几个关键词

先来说几个比较重要的关键词
**push_back( ) 成员函数在向量的末尾插入值,如果有必要会扩展向量的大小。
size( ) 函数显示向量的大小。
begin( ) 函数返回一个指向向量开头的迭代器。
end( ) 函数返回一个指向向量末尾的迭代器。**

下面我们上,👌将string和vector放到一起是因为:
在 STL 中,拥有 capacity 属性的容器只有 vector 和 string。

针对 capacity 这个属性,STL 中的其他容器,如 list map set deque,由于这些容器的内存是散列分布的,因此不会发生类似 realloc() 的调用情况,因此我们可以认为 capacity 属性针对这些容器是没有意义的,因此设计时这些容器没有该属性。

string

string有点像字符串,如果在c中我问你字符串的本质是什么?应该回答是指针,但是如果说string的本质是什么,那么就是类。

string和char指针的基本操作:

#include<string>
#include<iostream>
using namespace std;
void test01()
{
    string s1;
    const char *str = "aaa0";
    string s2(str);
    cout << s1<<endl<<s2;

    //调用拷贝构造函数
    string s3(s2);

    //
    string s4(10, 'a');
    cout << s4;
}
int main()
{
    test01();
    return 0;
}

string的基本赋值操作

#include<string>
#include<iostream>
using namespace std;
void test01()
{
    string s1;
    s1 = "hello C++";
    string s2;
    s2 = s1;
    string s3;
    s3 = 'a';
    string s4;
    s4.assign("hello c++");
    string s5;
    s5.assign("hello c++", 5);//前5个赋值给s5
    cout << s5 << endl;;

    string s6;
    s6.assign(s5);
    cout << s6 << endl;

    string s7;
    s7.assign(5, 'x');//5个x
    cout << s7 << endl;
}
int main()
{
    test01();
    return 0;
}

下面再来说几个string中常用的函数

先来第一个string的比较

//用字符ascll码进行比较
//=返回0
//>返回1,<返回-1
#include<string>
#include<iostream>
using namespace std;
void test01()
{
    string str1="hello";
    string str2 = "hello";
    if (str1.compare(str1)==0)
    {
        cout << "=";
    }
    else if (str1.compare(str2) > 0)
    {
        cout << ">";
    }
    else if (str1.compare(str2) < 0)
    {
        cout << "<";
    }
}
int main()
{
    test01();
    return 0;
    //在实际开发中主要是用来比较是否等于
}

下一个是string的查找

//若有重复字符则rfind()返回的是逆向查找到的字符在正向的位置
#include<iostream>
#include<string>
using namespace std;
//查找
void test01()
{
    string str1="jskkkskk";
    int a=str1.find("js");
    int b = str1.rfind("js");
    //如果找不到,返回-1
    cout << a<<" "<<b<<endl;

}
//替换
void test02()
{
    string str2 = "jkjjjssss";
    str2.replace(1, 3, "1111");
    //从1号开始,替换3个为4个1
    cout << str2;

}
int main()
{
    test01();
    test02();
    return 0;
}

查找的前提是存取吧,那么看存取

//at,size
#include<iostream>
#include<string>
using namespace std;
void test01()
{
    string str1 = "hello";
    for (int i = 0; i < str1.size(); i++)
    {
        cout << str1.at(i) << endl;
    }
    
    //修改
    str1.at(1) = 'a';
    str1[0] = 'a';
    for (int i = 0; i < str1.size(); i++)
    {
        cout << str1[i];
    }
}
int main()
{
    test01();
    return 0;
}

存进去,总要修改,再来一个

#include<iostream>
#include<string>
using namespace std;
void test01()
{
    string str1 = "hello";
    str1.insert(1, "111");
    //在第一个元素前插入
    cout << str1 << endl;
    str1.erase(1, 3);
    //erase是橡皮的意思,删除
    //表示从1开始删除3个
    cout << str1 << endl;

}
int main()
{
    test01();
    return 0;
}

下面是获取和拼接

#include<iostream>
#include<string>
using namespace std;
void test01()
{
    string str1;
    str1 += "ye";
    string str2;
    str2 = "jjff";
    str1 += str2;

    string str3="I";
    str3.append(" Love");
    str3.append("game abcde", 4);
    str3.append(str2, 2, 1);//从str2中开始的2,接1,拼接
    cout << str3;

}
int main()
{
    test01();
    return 0;
}

最后一个,string的截取

#include<iostream>
#include<string>
using namespace std;
void test01()
{
    string str1 = "javbjjj";
    string str2 = str1.substr(1, 2);
    cout << str2 << endl;
}
//来个邮箱吧
void test02()
{
    string str3 = "masheng@qq.com";
    int num = str3.find('@');
    string str4 = str3.substr(0, num);
    cout << str4;
}
int main()
{
    test01();
    test02();
    return 0;
}

vector

首先我们会发现vector像数组,那么它和数组最大 的区别是什么?
👍vector与数组最大区别就是动态扩展,不是续写,而是找一块更大的空间,拷贝原有的数据,释放原有的空间
他的构造形式有一下几种,一般没有具体的好坏,凭借心情使用

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> &v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}
void test01()
{
    vector<int> v1;//默认构造
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    print(v1);

    vector<int> v2(v1.begin(),v1.end());
    print(v2);

    vector<int> v3(10, 100);
    print(v3);

    vector<int> v4(v3);
    print(v4);
}
int main()
{
    test01();
    return 0;
}

下面是vector数据的存取,比较简单,相当于读入数据

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
}
void test01()
{
    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    v1.at(0) = 99;
    v1[0] = 98;
    print(v1);
}
int main()
{
    test01();
    return 0;
}

其中iterator是一个迭代器,这里我们存入了int型的变量,当然也可以存入其他的变量,例如,存入一个结构体

#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Person
{
public:
    Person(string name, int age)
    {
        m_name = name;
        m_age = age;
    }
public:
    string m_name;
    int m_age;
};
void test01()
{
    vector<Person> v;
    //创建数据
    Person p1("aaa", 10);
    Person p2("bbb", 20);

    v.push_back(p1);
    v.push_back(p2);

    for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << it->m_name << it->m_age << endl;
        cout << (*it).m_name << (*it).m_age << endl;
    }
}
void test02()
{
    vector<Person> v;
    //创建数据
    Person p1("aaa", 10);
    Person p2("bbb", 20);
    for (vector<Person*>::iterator it = v.begin(); it !=  v.end(); it++)
    {
        Person *p = *it;
        cout << p->m_name << (*it)->m_age << endl;
    }
}
int main()
{
    test01();
    return 0;
}

C++ STL 之 vector 的 💖capacity 和 size 属性💖区别
size 是当前 vector 容器真实占用的大小,也就是容器当前拥有多少个容器。
capacity 是指在发生 realloc 前能允许的最大元素数,即预分配的内存空间。

当然,这两个属性分别对应两个方法:resize() 和 reserve()。
使用 resize() 容器内的对象内存空间是真正存在的。
使用 reserve() 仅仅只是修改了 capacity 的值,容器内的对象并没有真实的内存空间(空间是"野"的)。
此时切记使用 [] 操作符访问容器内的对象,很可能出现数组越界的问题。

下面用代码来看一下

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> &v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
        
    }
    cout << endl;
}
void test01()
{
    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    if (v1.empty())
        cout << "weikong";//为真代表为空
    else
    {
        cout << "不为空";
        cout << v1.capacity()<<" ";//动态扩展到13
        cout << v1.size()<<" ";//大小
    }
    //重新指定大小
    v1.resize(15);//默认不够的都补为0
    v1.resize(15, 100);
    //自定义
    v1.resize(5);//超出的会删掉
    print(v1);
}
int main()
{
    test01();
    return 0;
}

vector的插入和删除所用的函数与string,大同小异
/*
push_back
pop_back
erase
clear
intsert
*/

#include<iostream>
#include<vector>
using namespace std;
void print(vector<int> v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
}
void test01()
{
    vector<int> v1;
    v1.push_back(10);
    v1.push_back(20);//尾插

    v1.pop_back();//尾删

    //插入
    v1.insert(v1.begin(), 100);
    v1.insert(v1.begin(), 2, 20);
    //删除,参数也是迭代器
    v1.erase(v1.begin());
    v1.erase(v1.begin(), v1.end());

    //清空
    v1.clear();
    print(v1);
}
int main()
{
    test01();
    return 0;
}

最后

🎉欢迎关注🔎点赞👍收藏⭐️留言📝
如果喜欢stl的话,未来3天更新完成

相关文章
|
1月前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
33 4
|
1月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(三)
【C++】C++ STL 探索:String的使用与理解
|
1月前
|
存储 编译器 C++
【C++】C++ STL 探索:String的使用与理解(二)
【C++】C++ STL 探索:String的使用与理解
|
1月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(一)
【C++】C++ STL 探索:String的使用与理解
|
25天前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
20 0
|
3月前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
3月前
|
存储 算法 程序员
【STL】string
【STL】string
|
4月前
|
算法 C++
STL算法大全
以上只是一部分STL算法的简单概述,每一个算法都有其特定的使用场景和规则,具体使用时需要参考相关文档或者教程进行深入理解和学习。
31 0
|
2月前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
36 0
java基础(13)String类
|
22天前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
45 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性