当前位置: 首页 > news >正文

2-刷力扣问题记录

25.2.13

1.to_string函数的作用是什么

to_string 是 C++ 标准库中的一个函数,用于将 数值类型 转换为 字符串

作用:

to_string 将数值类型(如 intfloatdoublelong 等)转换为对应的字符串表示形式。

用法:

#include <iostream>
#include <string>

int main() {
    int num = 123;
    double pi = 3.14159;

    std::string str_num = std::to_string(num);  // 将整数转为字符串
    std::string str_pi = std::to_string(pi);    // 将浮点数转为字符串

    std::cout << "Integer as string: " << str_num << std::endl;  // 输出: Integer as string: 123
    std::cout << "Double as string: " << str_pi << std::endl;    // 输出: Double as string: 3.141590
}

例子:

int num = 42;
std::string str = std::to_string(num);  // str = "42"

double pi = 3.14159;
std::string pi_str = std::to_string(pi);  // pi_str = "3.141590"

注意:

  • 对于 浮点数floatdouble 等),to_string 会保留小数点后六位(默认行为)。
  • to_string 适用于数值类型的转换,不支持直接将其他类型(如 charbool 等)转换为字符串。

小结:

to_string 是将数值类型转化为字符串的一个便捷工具,适用于在 C++ 中进行类型转换时使用。


25.2.15

1.为什么下面这行代码可以舍弃末尾元素: postorder.resize(postorder.size() - 1);

resize 函数

resize 是 C++ 标准库中 std::vector 类提供的一个成员函数,功能是改变向量的大小。如果新的大小小于当前大小,那么多余的元素会被移除;如果新的大小大于当前大小,则会添加默认构造的元素(比如 int 的话会填充 0char 会填充 '\0',等等)。

void resize(size_t new_size);
  • new_size 是你希望 vector 最终的大小。
  • 如果 new_size 小于当前的大小,vector 会被裁剪到新的大小,丢弃掉超出的元素。
  • 如果 new_size 大于当前的大小,vector 会扩展,并按元素类型的默认构造方法填充新的元素。

是的,resize 默认是通过舍弃末尾元素来调整 std::vector 的大小的


2.如何去掉第一个元素呢?

要去掉一个 vector 的第一个元素,可以通过几种方法来实现。以下是几种常见的方式:

方法 1:使用 erase 方法

vector::erase 可以用来删除 vector 中的元素。要删除第一个元素,可以使用 erase 方法删除下标为 0 的元素

vector<int> vec = {1, 2, 3, 4};
vec.erase(vec.begin());  // 删除第一个元素
// vec 现在是 {2, 3, 4}

方法 2:使用 vector::beginvector::end 重新构造一个新的子 vector

如果你想要得到一个没有第一个元素的新 vector,你可以使用 vector 的构造函数来创建一个新的子 vector,从而跳过第一个元素。

vector<int> vec = {1, 2, 3, 4};
vector<int> newVec(vec.begin() + 1, vec.end());  // 从第二个元素开始构建新的vector
// newVec 现在是 {2, 3, 4}

方法 3:使用 pop_front(如果是 deque

如果你使用的是 deque(双端队列),你可以直接使用 pop_front 方法删除第一个元素。vector 没有 pop_front 方法,但如果使用 deque,这种方法是很方便的。

deque<int> deq = {1, 2, 3, 4};
deq.pop_front();  // 删除第一个元素
// deq 现在是 {2, 3, 4}

选择方法

  1. 如果你只是想删除第一个元素并更新原始 vector,使用 erase 是最简单的方法。
  2. 如果你想生成一个新 vector,其中不包含第一个元素,使用 构造子 vector 的方法也很简洁。
  3. 如果你使用的是 deque 而不是 vector,可以使用 pop_front

对于 vector 类型,方法 1 和 2 都是常用的方案。


25.2.16

1.数组nums里的nums.begin()和nums.end()返回的是什么

nums.begin()nums.end() 返回的是 vector(或者其他标准容器)的 迭代器,它们用于指示容器的开始和结束位置。迭代器在 C++ 中类似于指针,用于访问容器中的元素。

nums.begin()

  • nums.begin() 返回一个 指向容器第一个元素的迭代器
  • 如果容器为空,begin() 会返回一个和 end() 相等的迭代器。

例如,假设你有一个 vector<int>

vector<int> nums = {10, 20, 30};
auto it = nums.begin();
cout << *it << endl;  // 输出:10,因为 it 指向第一个元素

nums.end()

  • nums.end() 返回一个 指向容器最后一个元素之后的位置的迭代器,也叫做“尾后迭代器”。
  • 它不指向容器的元素,而是指向一个超出容器范围的一个位置,表示容器的结束。
  • 迭代器 end() 不能解引用(即不能通过 *it 获取数据),因为它并不指向有效的元素。

例如:

vector<int> nums = {10, 20, 30};
auto it = nums.end();
cout << *(it - 1) << endl;  // 输出:30,因为 it - 1 指向最后一个元素

使用 begin()end() 遍历容器

begin()end() 通常用在 范围-based for 循环标准库算法 中,来遍历容器:

范围-based for 循环:

vector<int> nums = {10, 20, 30};
for (auto it = nums.begin(); it != nums.end(); ++it) {
    cout << *it << " ";  // 输出:10 20 30
}

使用 STL 算法(如 std::sort):

vector<int> nums = {30, 10, 20};
sort(nums.begin(), nums.end());  // 排序
for (int num : nums) {
    cout << num << " ";  // 输出:10 20 30
}

总结:

  • nums.begin() 返回一个指向容器第一个元素的迭代器。
  • nums.end() 返回一个指向容器最后一个元素之后位置的迭代器(尾后迭代器)。
  • 迭代器是 C++ 标准容器的一个重要概念,用来遍历、访问容器中的元素。

25.2.27

1.数组和列表分别是如何定义的,vector是啥,二维数组和列表是怎么定义的

在 C++ 中,数组、列表(std::list)、vector 和二维数组的定义方式各不相同。下面我将详细说明这些概念以及如何定义它们。

1. 数组 (Array)

数组是一个固定大小的数据结构,所有元素的类型相同,并且在内存中是连续存储的。

定义:

// 定义一个大小为 5 的整型数组
int arr[5];

// 定义并初始化一个数组
int arr[5] = {1, 2, 3, 4, 5};
  • 静态数组:定义时必须指定大小,且大小在定义时确定并不能改变。
  • 数组元素访问:可以通过下标来访问数组元素,arr[0] 是第一个元素,arr[4] 是最后一个元素。

注意:

  • C++ 中的数组大小是固定的,一旦定义好,大小无法改变。
  • 数组不提供直接的扩展、删除等功能。

2. std::vector

std::vector 是 C++ 标准库中的动态数组,它可以动态调整大小,能够在运行时增加或减少元素,非常灵活。

定义:

#include <vector>

// 定义一个空的 vector
std::vector<int> vec;

// 定义并初始化一个 vector
std::vector<int> vec = {1, 2, 3, 4, 5};
  • 动态大小vector 可以根据需要自动扩展,允许动态添加或删除元素。
  • 常用操作push_back() 添加元素,pop_back() 删除元素,size() 返回当前元素个数,at(index) 访问指定元素。
  • 访问:可以通过下标 vec[0]vec.at(0) 来访问元素。

示例:

std::vector<int> vec = {1, 2, 3};
vec.push_back(4);  // 在末尾添加元素
std::cout << vec[0] << std::endl;  // 输出 1

 3. std::list

std::list 是 C++ 标准库中的一个双向链表,允许在两端插入和删除元素,但与 vector 相比,随机访问较慢。

定义:

#include <list>

// 定义一个空的 list
std::list<int> lst;

// 定义并初始化一个 list
std::list<int> lst = {1, 2, 3, 4, 5};
  • 双向链表list 支持在任何位置插入和删除元素,但不支持像 vector 那样的高效随机访问。
  • 常用操作push_back() 添加元素,push_front() 在前面插入元素,pop_back() 删除末尾元素,pop_front() 删除开头元素。

示例:

std::list<int> lst = {1, 2, 3};
lst.push_back(4);  // 在末尾添加元素
lst.push_front(0); // 在前面添加元素
for (int num : lst) {
    std::cout << num << " ";  // 输出 0 1 2 3 4
}

4. 二维数组 (2D Array)

二维数组是由多个一维数组组成的数组,也称为矩阵。可以通过指定两层下标来访问二维数组中的元素。

定义:

// 定义一个 3x3 的二维数组
int arr[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 定义并初始化一个 2x3 的二维数组
int arr[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};
  • 访问元素:可以使用 arr[0][0] 来访问二维数组的元素,第一层下标对应行,第二层下标对应列。

示例:

int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
std::cout << arr[1][2] << std::endl;  // 输出 6

5. 二维 vector

在 C++ 中,vector 也可以用来创建二维结构,即通过创建一个包含 vectorvector

定义:

#include <vector>

// 定义一个 2x3 的二维 vector
std::vector<std::vector<int>> vec = {
    {1, 2, 3},
    {4, 5, 6}
};
  • 访问元素:可以使用 vec[i][j] 来访问二维 vector 中的元素。

示例:

std::vector<std::vector<int>> vec = {{1, 2, 3}, {4, 5, 6}};
std::cout << vec[0][2] << std::endl;  // 输出 3

6. 动态二维数组

如果你不知道二维数组的大小并且希望动态分配空间,可以使用 vector 动态创建二维数组。例如,可以创建一个大小为 m x n 的二维 vector

定义:

#include <vector>

// 定义一个 m x n 的二维 vector,元素初始值为 0
int m = 3, n = 4;
std::vector<std::vector<int>> vec(m, std::vector<int>(n, 0));
  • 这里创建了一个 3 行 4 列的二维 vector,并将所有元素初始化为 0

示例:

std::vector<std::vector<int>> vec(3, std::vector<int>(4, 0));  // 3x4 的二维 vector
vec[1][2] = 5;  // 设置元素
std::cout << vec[1][2] << std::endl;  // 输出 5

总结

  • 数组 (Array) 是静态的,大小固定,元素类型相同,存储在连续内存中。
  • vector 是动态数组,可以动态增加和删除元素,支持高效的随机访问。
  • std::list 是双向链表,支持高效的插入和删除操作,但不支持高效的随机访问。
  • 二维数组 是多个一维数组的组合,大小固定,访问方式是通过两个索引。
  • 二维 vector 是由 vector 组成的 vector,允许动态调整大小,适用于不确定大小的矩阵。

通过这些数据结构,可以根据需求选择最合适的方式来存储和操作数据。


2.字符串使用双引号和单引号有什么区别

在 C++ 中,双引号")和单引号')有不同的用途和意义。下面是它们的主要区别:

1. 双引号 "

  • 表示字符串字面量:双引号用于定义字符串常量(string literals),即由多个字符组成的字符串。

    • 字符串类型:双引号中的内容是一个字符串,类型为 std::stringchar[](字符数组)。
    • 自动包含结束符:字符串的末尾会自动添加一个空字符(\0),用于标志字符串的结束。

示例:

std::string str = "Hello, World!";

这里的 "Hello, World!" 是一个字符串字面量,它是 std::string 类型。

const char* str = "Hello, World!";

这里的 "Hello, World!" 是一个 const char* 类型的字符串。

2. 单引号 '

  • 表示字符字面量:单引号用于定义单个字符字面量,即只有一个字符的数据。

    • 字符类型:单引号中的内容是一个字符,类型为 char
    • 不能包含多个字符:单引号只允许包含一个字符。如果包含多个字符,编译器会报错。

示例:

char c = 'H';

  • 这里的 'H' 是一个字符字面量,它是 char 类型。

3. 区别总结

区别双引号 " "单引号 ' '
表示的内容字符串(多个字符)单个字符
类型std::stringchar[]char
结束符自动包含空字符(\0没有结束符
多个字符允许不允许,只有一个字符

4. 实际应用示例

双引号:

std::string str = "Hello";

这里的 str 是一个字符串变量,内容为 "Hello"

单引号:

char ch = 'H';
  • 这里的 ch 是一个字符变量,内容为 'H'

不允许多字符的例子:

char invalid = 'Hello';  // 错误!不能在单引号中放置多个字符

5. 总结

  • 双引号:用于表示字符串字面量,std::string 类型,支持多个字符。
  • 单引号:用于表示单个字符字面量,char 类型,只能包含一个字符。

希望这能帮助你理解双引号和单引号的区别!


3.string str = s.substr(startIndex, i-startIndex+1)是什么意思

1. substr(pos, len) 的含义

substrstd::string 类的一个成员函数,格式如下:

string substr(size_t pos, size_t len);
  • 参数 pos:从 pos(索引)位置开始截取子串。
  • 参数 len:要截取的长度
  • 返回值:返回截取后的子串。

2. s.substr(startIndex, i - startIndex + 1) 解析

  • startIndex 是起始索引(pos)。
  • i - startIndex + 1 计算的是子串的长度len)。

由于 i - startIndex 计算的是从 startIndexi 之间的字符个数,但 substrlen 是基于长度而不是索引,因此要加 1,确保包含 i 位置的字符。


3. 例子

假设 s = "abcdef",并且:

int startIndex = 1;  // 从索引 1 开始
int i = 3;  // 目标索引是 3
string str = s.substr(startIndex, i - startIndex + 1);
  • s.substr(1, 3 - 1 + 1) == s.substr(1, 3)
  • s 的索引从 0 开始:
s = "abcdef"
     012345

substr(1, 3) 提取的是 s[1] 开始,长度为 3 的子串,即 "bcd"


4."abcdef"获得子串a可以写成s.substr(startIndex, i - startIndex + 1)吗,难道不应该是s.substr(0, 0)

s.substr(0, 0) 是如何工作的?

  • s.substr(0, 0) 会从字符串 s 的第 0 个字符开始,截取长度为 0 的子串。
  • 结果是一个空字符串 "",并不是 "a"

但要提取 "a",应该用 s.substr(0, 1)

string s = "abcdef";
string sub = s.substr(0, 1);  // 获取 "a"

这才会得到 "a",因为 s.substr(0, 1) 从索引 0 开始,截取长度为 1 的子串。


为什么你会看到 s.substr(startIndex, i - startIndex + 1)

这种形式通常用于动态确定起始位置和长度。例如:

  • startIndex 是子串的起始位置。
  • i - startIndex + 1 是根据目标索引 i 动态计算出来的长度

举个例子:

假设字符串 s = "abcdef",你想从索引 0 到索引 0 获取子串 "a",可以这样写:

int startIndex = 0;
int i = 0;
string sub = s.substr(startIndex, i - startIndex + 1);  // 从索引 0 开始,长度为 1

这个写法的 i - startIndex + 1 计算结果为 1,表示子串的长度为 1,因此你会得到 "a"

总结:

  • s.substr(0, 0) 提取的是一个空字符串 "",并不包括字符 "a"
  • s.substr(0, 1) 提取的是从索引 0 开始的一个字符 "a"
  • s.substr(startIndex, i - startIndex + 1) 这种形式用于在动态计算起始位置和长度时非常有用,它可以灵活地处理各种索引和子串长度的情况。

相关文章:

  • .py文件和.ipynb文件的区别:完整教程
  • 【安装配置教程】在linux使用nginx部署vue项目
  • 【玩泰山派】5、点灯,驱动led (使用python库操作)
  • GMSL 使用 GPIO Forward 功能实现 Frame Sync
  • MetaGPT深度解析:重塑AI协作开发的智能体框架实践指南
  • 云服务器租用费用都受哪些因素影响?
  • QML实现RTSP以及本地解码播放
  • spring cloud OpenFeign 详解:安装配置、客户端负载均衡、声明式调用原理及代码示例
  • 系分论文《论面向服务开发方法在设备租赁行业的应用》
  • 软考高级-系统架构设计师 其他知识补充
  • Laravel源码进阶
  • AWTK-MVVM 如何让多个View复用一个Model记录+关于app_conf的踩坑
  • 再看 MPTCP 时的思考
  • Spring 是如何解决循环依赖的?
  • Redis-分布式锁
  • Shell打印命令返回的数组只显示第一个元素
  • 云豹录屏大师:多功能免费录屏工具
  • Maven 的安装与配置(IDEA)
  • 本地Docker部署开源Web相册图库Piwigo与在线远程访问实战方案
  • TypeScript入门
  • 百度收录网站与手机版/推广策略及推广方式
  • 网站结构图怎么做/宁波seo搜索排名优化
  • b2b建设网站/网站运营和维护
  • 东莞网站推广优化/济源网络推广
  • 丰台b2c网站制作价格/seo在哪学
  • 老板办公室装修设计/网站排名seo培训