C++: String类接口学习

文章目录

  • STL简介
  • 一. 为什么要有string类
  • 二. STL 中的 string 类介绍
    • 1. string 类描述
    • 2. 关于 basic_string
  • 三. string 类的常用接口
    • 1. string 类的常见构造
    • 2. string 类的容量操作
      • size 和 length
      • capacity
      • max_size
      • reserve
      • resize
    • 3. string 类对象的访问及遍历操作
      • operator[] 和 at()
      • 使用迭代器进行遍历
      • 范围 for (C++11)
    • 4. string类的修改操作
      • push_back
      • append
      • operator+=
    • 5.string 类对象的操作
      • c_str
      • find 和 substr

本章开始, 进入学习 C++ STL 的阶段, 现简单了解一下什么是 STL

STL简介

STL(standard template libraru -标准模板库): 是C++标准库的重要组成部分, 不仅是一个可复用的组建爱你哭, 而且是一个包罗数据结构与算法的软件框架.

STL的版本
市面上最常用的是 P.J.版本(被Windows Visual C++ 采用)和 SGI版本(被GCC采用)

STL六大组件

在这里插入图片描述

一. 为什么要有string类

在C语言中, 已经学习过字符串了.

C语言中, 字符串是以 \0 为结尾的一些字符的集合.
为了操作方便, C标准库 <string.h> 提供了一些处理字符串的库函数.
但是这些库函数是与字符串分开的, 不符合 OOP 的思想, 而且底层空间需要用户自己管理, 稍不留神就可能出现越界访问.

string类比STL出现的要早, 原因就是 string 的使用太常见了, 最后将 string 归入 STL 中.

二. STL 中的 string 类介绍

1. string 类描述

在 STL 中最常用的一个数据结构就是 string .

  • 字符串是表示字符序列的对象.
  • 标准 string 类提供的借口类似与 standard container 所提供的字符接口, 同时专门增加了操作 single-byte 字符串的设计特性
  • string 类是 basic_string<char> 模板的实例, 并用 char_traitsallocator 作为 basic_string 的默认参数
  • string 类独立于所使用的编码来处理字节, 如果用来处理多字节或者变长字符(如 UTF-8) 的系列, string 类仍然按照字节来操作, 而不是按照实际编码的字符来操作.

总结

  1. string 是表示字符串的字符串类.
  2. 该类的接口与常规容器的接口基本相同, 再添加了一些专门操作 string (例如单字节字符串)的常规操作.
  3. string 在底层实际是: basic string 模板类的别名.
typedef basic_string<char, char_traits, allocator> string;
  1. 不能操作多字节或者变长字符的序列.

使用 string 类, 需要:

#include<string>    // 使用 string 类需要引入头文件
using std::string   // string 标识在命名空间 std 中

2. 关于 basic_string

通过查看文档,可以看到 basic_string 是一个模板

template < class charT, 
class traits = char_traits<charT>,    // basic_string::traits_type           
class Alloc = allocator<charT>        // basic_string::allocator_type           
> class basic_string;

这里的 charT 表示实例化后的类需要按照 charT 类的字符处理字符串.

根据不同的 charT 类, 可以生成四种字符串类
在这里插入图片描述

UTF-8 就是一个字符有 8bit, 众所周知 char 类型的一个数据有 8 bit.
wstring 常用来处理 Unicode 类型的字符
还有UTF-16, UTF-32字节编码类型.

对于 stringbasic_string 模板实例化的一个类就可以很好理解了

typedef basic_string<char, char_traits, allocator> string;

string 就是用来处理 单字节字符的字符串, 不适用于用来处理变长字符或者多字节字符串.
其他字符串有 basic_string 模板实例化的其他类来处理.

三. string 类的常用接口

1. string 类的常见构造

官方文档 C++98 下的所有 string 类构造函数:

在这里插入图片描述

重点掌握:

string()                  //构造空的 string 类对象, 即空字符串
string(const char* s)       //使用 C-string 来构造 string 对象
string(size_t n, char c)  //string 类对象中包含 n个字符c
string(const string &c)   //拷贝构造函数

代码演示:

int main()
{
  // string()
  string s1 = string(); // 无参构造

  // string(const char *s)
  string s2 = string("Hello string"); // 使用C格式字符串构造

  // string(size_t n, char c)
  string s3 = string(4, 'c'); // 使用 4个c字符 构造

  // string(const string& s)
  string s4 = string(s3); // 拷贝构造
}

在这里插入图片描述


string(const string& str, size_t pos, size_t len = npos)
// 用 str 从 [pos, pos+len) 来拷贝构造.
// 如果范围超过了 pos位置到字符串末尾的长度, 拷贝到字符串结尾就停止了.

这里的 npos 是最大的 size_t, 在 64 位下就是 2 64 − 1 = 9223372036854775808 2^{64}-1 = 9223372036854775808 2641=9223372036854775808, 它是 string 类的静态成员, 使用 string::npos

在这里插入图片描述

代码演示:

int main()
{
  string s1 = string("12345678");
  string s2 = string(s1, 1, 5);     // [1, 6)
  string s3 = string(s1, 0);        // [0, s1.size()) 第三个参数不写默认用缺省值 npos
}

在这里插入图片描述


补充

string 类同样重载了 = , 可以直接按照下面的格式, 编译器会直接优化成用该C格式字符串进行构造.

string s1 = "Hello string";

2. string 类的容量操作

函数名称功能说明
size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty检测字符串是否位空串, 是返回 true, 否则返回 false
max_size返回字符串可取的最大有效字符长度
clear清空有效字符
reserve为字符串预留空间
resize将有效字符的个数改成n个, 多出的空间用字符c填充

size 和 length

size_t size() const;
size_t length() const;

size()length()都是得到字符串的有效长度, 两者没有区别.

int main()
{
  string s1;
  cout << "Please input a string: ";
  cin >> s1;

  cout << "Your input: " << s1;
  cout << "s1.size(): " << s1.size() << endl;
  cout << "s1.length(): " << s1.length() << endl;

  return 0;
}

程序运行结果:
在这里插入图片描述

注意:
size()length() 不包括 \0 , \0 是结尾标识符, 不被算作字符串的长度.

length()的出现是要比 size() 要早的. 一开始 string 类出现的时候并没有 STL, STL 其他很多容器计算大小都是使用 size()
为了将 string 放入 STL, 也让 string 类拥有了 size() 方法, 两者在底层是一模一样的.

size()length() 的底层源码: 甚至 length() 底层是直接调用 size()

size_type size() const { return _M_finish - _M_start; } //有效字符的个数,finish永远指向\0

size_type length() const { return size(); }

capacity

size_t capacity() const;

capacity() 得到当前 string 对象的可存放有效字符的容量值, capacity >= size, 如何扩容取决于编译器底层扩容机制

下面写一个程序用来测试 g++(Linux) 的扩容机制

int main()
{
  string s1 = string();
  size_t old_capacity = s1.capacity();
  cout << old_capacity << endl;

  for (int i = 0; i < 500; i++)
  {
    s1.push_back('x');
    if (old_capacity != s1.capacity())
    {
      old_capacity = s1.capacity();
      cout << old_capacity << endl;
    }
  }

  return 0;
}

发现在Linux下 g++编译器的扩容机制是这样的: 第一次直接开 15 个字符的空间, 之后每次扩容为当前容量的两倍.

在这里插入图片描述

max_size

size_t max_size() const;

max_size() 可以返回字符串的最大长度

int main()
{
  string s1;
  cout << s1.max_size() << endl;
  
  return 0;
}

程序运行结果如下: 在这里插入图片描述, 转换为 16进制: 0x3FFFFFFFFFFFFFFF, 结果是 int 类型可取最大正整数 2^63-1 的一半.

max_size() 所返回的数不能保证真的能创建一个这么大容量的 string 类对象, 程序很有很有可能报异常.

在这里插入图片描述

max_size() 的主要作用就是通过得到的返回值可以得到系统或者库中实现的限制, 提醒不能超过这么大的容量, 实践中参考和使用价值并不大.

reserve

void reserve(size_t n = 0);

reserve() 可以申请为 string 类扩容, 使得扩容后的 capacity 可以存放输入参数长度的字符串. 不一定就会扩容输入参数, capacity >= n 即可(例如输入500, 不一定会只开500)

  • 如果 n > capacity, 编译器会将 capacity 扩容至 n(可能大于n)
int main()
{
  string s1("Hello,world");
  cout << "size: " << s1.size() << endl;
  cout << "begin: " << s1.capacity() << endl;

  // n > size
  s1.reserve(300);
  cout << "n > size: " << s1.capacity() << endl;

  return 0;
}

程序运行如下: 在 Linux g++ 下, s1capacity 被扩容至了 n
在这里插入图片描述

  • 如果 n < capacity, capacity 不会被改变
int main()
{
  string s1("Hello,world");
  cout << "size: " << s1.size() << endl;
  cout << "begin: " << s1.capacity() << endl;

  s1.reserve(13);
  cout << "s1.reserve(13): " << s1.capacity() << endl;

  s1.reserve(1);
  cout << "s1.reserve(1): " << s1.capacity() << endl;

  return 0;
}

程序运行结果如下: n < capacity 时, 无论 n 是比 size 大还是小, 都不会对 capacity 进行改变

在这里插入图片描述

总结:reserve 只提供扩容功能, 不会对原本的数据进行修改.

resize

void resize(size_t n);
void resize(size_t n, char c);

resize() 会修改 string 类对象的 sizen

  • 如果 n > capacity, 将 capacity 扩容至少到 n, 同时插入字符(默认是'\0')至 sizen

  • 如果 n <= capacity && n >= size , 直接尾插字符, 容量不变

  • 如果 n < size, 将 n 位置字符替换为 0, 容量不变

  • n > capacity

int main()
{
  string s1 = "1234567890";
  cout << "begin\nsize: " << s1.size() << "\ncapacity: " << s1.capacity() << endl << endl;

  // n > capacity
  s1.resize(40);
  cout << "after s1.resize(40)\nsize: " << s1.size() << "\ncapacity: " << s1.capacity() << endl;
}

程序运行结果:
注意: 只有字符串中最后一个'\0'会被认为是结尾标识符, 前面的'\0'都是有效字符
在这里插入图片描述

  • n <= capacity && n >= size
s1.resize(13);
cout << "after s1.resize(13)\nsize: " << s1.size() << "\ncapacity: " << s1.capacity() << endl;

程序运行结果:
在这里插入图片描述

  • n < size
s1.resize(5);
cout << "after s1.resize(5)\nsize: " << s1.size() << "\ncapacity: " << s1.capacity() << endl;

程序运行结果为:

在这里插入图片描述

resize() 常用作在知道需要开很大空间的前提下, 提前开空间进行初始化, 避免重复扩容, 扩容消耗很大.

3. string 类对象的访问及遍历操作

函数名称功能说明
operator[]返回 pos 位置的字符, const string 类对象调用
begin + endbegin 获取第一个字符的迭代器 + end 获取最后一个字符下一个位置的迭代器
rbegin + rendrbegin 获取最后一个字符的迭代器 + rend 获取第一个字符前一个位置的迭代器
范围 forC++11支持更简洁的范围 for 的新遍历方式

operator[] 和 at()

如果想要访问字符串的元素, 可以使用[] 来访问, 并使用 for 循环来遍历字符串

int main()
{
  string s1 = "hello world!";

  for (size_t i = 0; i < s1.size(); i++)
  {
    cout << s1[i]; // 使用 operator[] 访问每个字符
  }

  cout << endl;
}

就像使用 for 循环遍历数组一样, 通过 [] 解引用访问每一个数组元素.

这里的 []运算符重载, 同等于下面的形式, 即 operator[], s1 通过调用运算符重载来达到访问该位置元素的效果, 传入参数为元素的下标序号(index position)

cout << s1[i];   
cout << s1.operator[](i) <<;  // 返回下标为 i 的元素的引用

如果想要修改该位置的元素, 也是可以通过 [] 进行修改的

int main()
{
  string s1("helloworld");

  for (size_t i = 0; i < s1.size(); i++)
  {
    ++s1[i];    // 对 s1 的每个字符都加1
  }

  cout << s1 << endl;
}

程序结果为: 在这里插入图片描述

operator[] 运算符重载有两种形式

char& operator[] (size_t pos);              // 可读可写
const char& operator[] (size_t pos) const;  // 只读不可写

为了让运算符重载支持对原位置元素的修改, 需要返回 char& 对原位置元素的引用.
同时也提供 cosnt 版本, 调用运算符重载的对象是一个 const 对象时, 通过对原位置的 const 引用, 以达到不可修改的作用.


at()[] 起到的作用都是一样的, 取到下标为 i 的元素, 可以对其进行修改.

唯一的区别是两者对越界的处理.

  • [] 可以访问 [ 0 , s i z e ] [0, size] [0,size] 的元素, 如果越界直接断言, 程序停止.
  • at() 可以访问 [ 0 , s i z e ) [0, size) [0,size) 的元素, 如果越界会报异常, 处理相对温和.

在这里插入图片描述

在这里插入图片描述

但一般情况还是 [] 用的比较多.

还有一个需要注意的点:
下标的是一个 size_t 类型, 即 string::size_type. 但一般写 int 类型的就可以了. 64位机器下, 对于小于 2 63 − 1 2^{63}-1 2631的下标, intsize_t 是一样的, 如果为了规范, 当然是更推荐写 size_t 类型.


使用迭代器进行遍历

迭代器(iterator)是 C++ STL的组件之一, 作用是用来遍历容器

int main()
{
  string s1 = "Hello,world!";

  string::iterator it = s1.begin();
  while (it != s1.end()){
    cout << *it << " ";
    ++it;
  }

  cout << endl;
}

程序运行结果: 在这里插入图片描述

iterator 的用法是指针, 但是不一定是指针, 目前使用它只要像使用指针一样.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

it 的类型是 string::iterator, iteratorstring 类的成员变量.

iterator 遍历对于像 string 这样底层连续的容器看起来不如使用 [] 来的直接简便.
但是对于物理结构非线性的结构却十分高效, 例如链式结构, 树形结构, 哈希结构这样的容器, 是不可以用 [] 的形式来遍历访问到每一个元素的.
因为 [] 在底层本质是通过相对于首元素的偏移量来访问到对应元素的. 而上述结构在物理结构上并不是连续的, 不可以通过偏移量来访问到每个元素.

iterator不用关心底层是怎么实现的, 通用性更强. 上述用来 iterator 遍历同样适用于非线性结构.

如果想要反向遍历, 也有对应的 rbeginrend 使用, 要使用反向迭代器类 reverse_iterator

int main()
{
  string s1("Hello,world!");

  string::reverse_iterator it = s1.rbegin();
  while (it != s1.rend()){
    cout << *it;
    ++it;
  }

  cout << endl;
}

程序运行结果是: 在这里插入图片描述

在这里插入图片描述


下面是 string 类的所有迭代器类成员变量
在这里插入图片描述

如果容器对象是 const 对象, 也有对应的 const_iterator.
不同于 const iterator , const_iterator 限制的是不可以通过对指向容器的元素进行修改, 而 const iterator 则是限定了 it 不可以修改, 这显然是不对的.

同样的, beginend, rbeginrend 也重载了 const 修饰的成员函数
在这里插入图片描述

如果不想让迭代器对原数据进行修改, 可以这样定义 it

string::const_iterator it = s1.begin();

编译器会自动使用 begin()const形式.

C++11 新增了 cbegin, cend, crbegin, crend; 这些仅有 const 版本, 但是并不实用.

范围 for (C++11)

C++11添加了范围 for 的语法, 配合 auto 关键字, 可以更为简洁地进行遍历

int main()
{
  string s1 = "Hello,world";

  // 编译器将 auto 推导为 string::iterator
  for (auto e: s1){
    cout << e;
  }
  cout << endl;
}

程序运行结果为: 在这里插入图片描述

其实底层仍然是使用迭代器进行遍历, 只是看起来更为简洁. 配合 auto 可以使整个代码大大缩短, 但是降低了程序可读性.

配合引用, 也可以进行原数据上的修改

int main()
{
  string s1 = "Hello,world";

  for (auto& e: s1){
    ++e;
  }
  cout << s1 << endl;
}

程序运行结果为: 在这里插入图片描述

4. string类的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=在字符串后追加字符串str

push_back

void push_back(char c);

只能尾插一个字符, 不可以尾插字符串.

int main()
{
  string s = "abcde";
  s.push_back('f');
  cout << s << endl;

  return 0;
}

在这里插入图片描述

append

在这里插入图片描述

append() 就可以尾插一个字符串, 也可以尾插一个 string 类对象

int main()
{
  string s = "abcde";
  s.append("fg"); // 尾插c格式串
  cout << s << endl;

  string s1 = "hijklm";
  s.append(s1); // 尾插string类对象
  cout << s << endl;

  return 0;
}

程序运行结果如下: 在这里插入图片描述

注意:插入字符需要指定数量, 只写插入的字符.

int main()
{
  string s = "abcdef";
  s.append(1, 'g');
  cout << s << endl;
  
  return 0;
}

程序运行结果如下: 在这里插入图片描述

operator+=

在这里插入图片描述

一般更加常用的是 operator+=, 既可以尾插字符,也可以尾插字符串

int main()
{
  string s = "12345";
  s += '6';             // 尾插字符
  s += "789";           // 尾插字符串
  s += string("0000");  // 尾插string类对象

  cout << s << endl;
  return 0;
}

程序运行结果: 在这里插入图片描述

5.string 类对象的操作

函数名称功能说明
c_str返回c格式字符串
find+npos从字符串pos位置开始往后找字符c, 返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c, 返回该字符在字符串中的位置
substr在str中从pos位置开始, 截取n个字符, 然后将其返回

c_str

const char *c_str() const;

返回一个指向 string 类对象的 c格式字符串(以'\0'为结尾) 成员的const 指针

在一些只有C格式字符串接口的操作中, 该函数的作用就体现了.
例如一些嵌入式程序, 以及下面的文件读写操作.

如果想用 C语言 的文件操作相关函数, 必须要传 C格式字符串 才可以找到该文件(即 const char *)

string file("file.txt");
FILE *fp = fopen(file.c_str(), "r");

find 和 substr

如果要取文件名的后缀, 使用 find() 就可以很快的找到 . 的位置
在这里插入图片描述

find() 可以从 pos 位置开始找要查找的目标, 如果找到返回首元素下标, 如果没找到返回 string::npos

同时结合 sbustr() 可以截取指定长度的字符串, 第二个参数缺省值为 npos

在这里插入图片描述

int main()
{
  string file = "hello.c";
  size_t pos = file.find('.', 0); // 找到 . 的位置

  if (pos != string::npos){
    cout << file.substr(pos) << endl; // 截取 . 位置之后的字符串
  }

  return 0;
}

程序运行结果如下: 在这里插入图片描述

通过分离网址, 再熟悉一下 find()substr() 的操作

int main()
{
  string str("https://legacy.cplusplus.com/reference/string/string/substr/");

  size_t pos1 = str.find(':');
  cout << str.substr(0, pos1 - 0) << endl;

  size_t pos2 = str.find('/', pos1 + 3);
  cout << str.substr(pos1 + 3, pos2 - pos1 - 3) << endl;

  cout << str.substr(pos2 + 1) << endl;

  return 0;
}

程序运行结果如下: 在这里插入图片描述

本章完.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/196157.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

centos服务器扩容

centos服务器扩容 我的情况是&#xff0c;原服务器是一个80g磁盘&#xff0c;管理员又追加了120G到这块磁盘上&#xff0c;需要把这120G重新追加使用。 请确认你遇到的情况是否和我初始截图一致&#xff0c;再往下看&#xff0c;免得浪费时间与精力 服务器中有120G尚未使用&…

典型的SAST支持检测标准

这里我们列举了Coverity、Cobot、代码卫士、Klocwork、QAC、C test几款典型的SAST工具&#xff0c;看看他们都是支持那些C、C标准&#xff08;主要是C、C标准&#xff0c;其它语言较少&#xff09;呢&#xff1f; 这可以作为厂商研发的方向标。 &#xff08;结束&#xff09;

更高效的图片预览方案

传统的图片预览方式是什么样子的呢&#xff1f; 首先是用户选择一张图片&#xff0c;通过ajax上传到服务器&#xff0c;然后服务器返回一个访问url 然后给img标签的src属性设置这个访问url。 那这就会有一个问题&#xff0c;用户为什么要先网络上传上去再预览呢&#xff0c;我…

docker容器的生命周期管理常用命令

容器的生命周期管理命令 docker create &#xff1a;创建一个新的容器但不启动它 docker create nginx docker run :创建一个新的容器并运行一个命令 常用选项&#xff1a; 常用选项1. --add-host&#xff1a;容器中hosts文件添加 host:ip 映射记录 2. -a, --attach&#…

银行各类计算公式汇总

一、存款准备金 存款准备金&#xff0c;分为法定存款准备金和超额存款准备金&#xff08;主要构成是存放央行及现金&#xff0c;不包括存放同业资金&#xff09;。下表为目前最新的各类银行业金融机构存款准备金水平。 法定存款准备金率是指中央银行规定的&#xff0c;存款性…

python如何抓取携程酒店的价格,让工作更简单点

有时候老板没事安排点事&#xff0c;为了偷懒&#xff0c;只能使出大招&#xff0c;毕竟自己不是那么老老实实干活的人&#xff0c;整理数据这类累和繁琐的活&#xff0c;我怎么能轻易动&#xff0c;好在gpt可以帮我来实现&#xff0c;有人可能会说&#xff0c;这么点内容你还不…

深入理解main方法-Java

深入理解main方法-Java 一、语法说明二、特别说明三、动态传值 一、语法说明 public static void main(String[] args)main方法是虚拟机调用的java虚拟机需要调用类的main()方法&#xff0c;所以该方法的访问权限必须是publicjava虚拟机在执行main()方法时不必创建对象&#x…

djangorestframework modelserializer 处理关系字段

djangorestframework modelserializer 处理关系字段 1.关系 一对一、多对一、多对多 2.drf modelserializer对关系字段的处理 modelserializer默认处理关系字段为PrimaryKeyRelatedField&#xff0c;默认是id-pk。 多对一&#xff1a;直接写入id 多对多&#xff1a;写入id-lis…

科东快讯 | Intewell鸿道工业操作系统亮相丝路峰会暨中国新工业博览会

近日&#xff0c;第十六届中国工业论坛丝路峰会暨中国新工业博览会在陕西西安临空会展中心圆满落幕&#xff01; 峰会围绕“十四五”工业经济高质量发展的新使命、新担当&#xff0c;以“新工业新动能新格局”为主题&#xff0c;聚焦新兴工业领域&#xff0c;突出新工业产业集…

队列的实现

1.队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾出队列&#xff1a;进行删除操作的一端称为队头 …

媒介盒子分享:实用软文写作技巧

信息洪流中品牌方如果想要抓住用户注意力就需要一定的技巧&#xff0c;而品牌方写软文时是不是经常面临无法与用户产生共鸣、软文没有转化率的困境。今天媒介盒子就来和大家分享&#xff1a;实用软文写作技巧。 一、 强化优势 人一定是会往自己喜欢的方向走&#xff0c;远离不…

图解系列--Web服务器,Http首部

1.用单台虚拟主机实现多个域名 HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点。。比如&#xff0c;提供 Web 托管服务&#xff08;Web Hosting Service&#xff09;的供应商&#xff0c;可以用一台服务器为多位客户服务&#xff0c;也可以以每位客户持有的域名运行各自不…

深度视觉目标跟踪进展综述

1 引言 目标跟踪旨在基于初始帧中指定的感兴趣目标( 一般用矩形框表示) &#xff0c;在后续帧中对该目标进行持续的定位。 基于深度学习的跟踪算法&#xff0c;采用的框架包括相关滤波器、分类式网络、双路网络等。 处理跟踪任务的角度&#xff0c;分为基于匹配思路的双路网…

算法通关第十七关白银挑战——贪心算法的高频算法题

大家好&#xff0c;我是怒码少年小码。 今天早上起来的时候发现我的一篇公众号的文章火了&#xff01;超级开心&#xff01;原来这就是有流量支持的底气嘛~ 书接上文&#xff0c;本篇主要讲解贪心思想的几个经典例题。 区间问题 判断区间是否重叠 LeetCode 252&#xff1a…

Leetcode—15.三数之和【中等】

2023每日刷题&#xff08;四十一&#xff09; Leetcode—15.三数之和 实现代码 class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());vector<vector<int>> ans;int i, j, k;int s,…

移植NXP官方uboot到IMX6ULL开发板--以及过程中遇到的疑问和错误记录

目录 1 下载uboot源码 2在uboot中添加自己的开发板 2.1 添加开发板默认配置文件 疑问&#xff1a;defconfig文件里面为什么没有CONFIG_SYS_EXTRA_OPTIONS"IMX_CONFIGboard/freescale/mx6ullevk/imximage.cfg,MX6ULL_EVK_EMMC_REWORK" 2.2 添加开发板对应的头文…

k8s中pod的hostport端口突然无法访问故障处理

故障背景&#xff1a; 租户告知生产环境的sftp突然无法访问了&#xff0c;登录环境查看sftp服务运行都是正常的&#xff0c;访问sftp的hostport端口确实不通。 故障处理过程 既然访问不通那就先给服务做个全面检查&#xff0c;看看哪里出了问题&#xff0c;看下sftp日志&#…

VIR-SLAM代码分析2——VIR_VINS详解

前言 VIR-SLAM中VIR_VINS文件夹下是基于VINS-mono的结合UWB传感器的估计器&#xff0c;主要改动的文件在uwb_posegraph&#xff0c;vir_estimator中。其他文件夹完成的是UWB数据的处理问题&#xff0c;比较简单上一节介绍足够&#xff0c;代码也容易看懂。本节介绍的VIR_VINS是…

软件测试简历编写技巧,对症下药,一周面10家...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 作为HR来说&#…

吉利银河L6 纯电模式 空调加热功率

环境 环境10摄氏度左右 空调加热最高档 风速最高档 慢充充电 地下车库 开空调充电 关空调充电 分析 充电功率6kw 开关空调时间差了一倍 所以估算出空调加热峰值功率大概3kw左右
最新文章