【C++】30h速成C++从入门到精通(STL介绍、string类)

news2024/11/18 4:41:43

STL简介

什么是STL

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

STL的版本

  • 原始版本

Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。

  • P.J.版本

由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。

  • RW版本

由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。

  • SGI版本

由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码主要参考的就是这个版本。

STL的六大组件

仿函数、算法、迭代器、空间适配器、容器、配接器

STL的缺陷

  1. STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出来已经相隔了13年,STL才进一步更新。

  1. STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。

  1. STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。

  1. STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语法本身导致的。

string类

为什么学习string类

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

标准库中的string类

string类的文档介绍:

https://cplusplus.com/reference/string/string/?kw=string

  1. 字符串是表示字符序列的类

  1. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。

  1. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。

  1. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。

  1. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

总结:

  1. string时表示字符串的字符串类。

  1. 该类的接口与常规容器接口基本相同,再添加了一些专门用来操作string的常规操作。

  1. string在底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits,allocator> string;

  1. 不能操作多字节或者变长字符的序列。

string类的常用接口说明(最常用的接口)

  • string类对象的常见构造

(constructor)函数名称

功能说明

string()

构造空的string类对象,即空字符串

string(const char* s)

用C-string来构造string类对象

string(size_t n,char c)

string类对象中包含n个字符c

string(const string& s)

拷贝构造函数

void Teststring()
{
 string s1; // 构造空的string类对象s1
 string s2("hello bit"); // 用C格式字符串构造string类对象s2
 string s3(s2); // 拷贝构造s3
}

string类对象的容量操作

函数名称

功能说明

size

返回字符串有效字符长度

length

返回字符串有效字符长度

capacity

返回空间总大小

empty

检测字符串释放为空,是返回true,否则返回false

clear

清空有效字符

reserve

为字符串预留空间

resize

将有效字符的个数改成n个,多出的空间用字符c填充

// size/clear/resize
void Teststring1()
{
 // 注意:string类对象支持直接用cin和cout进行输入和输出
 string s("hello, bit!!!");
 cout << s.size() << endl;
 cout << s.length() << endl;
 cout << s.capacity() << endl;
 cout << s <<endl;
 
 // 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
 s.clear();
 cout << s.size() << endl;
 cout << s.capacity() << endl;
 // 将s中有效字符个数增加到10个,多出位置用'a'进行填充
 // “aaaaaaaaaa”
 s.resize(10, 'a');
 cout << s.size() << endl;
 cout << s.capacity() << endl;
 // 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
 // "aaaaaaaaaa\0\0\0\0\0"
 // 注意此时s中有效字符个数已经增加到15个
 s.resize(15);
 cout << s.size() << endl;
 cout << s.capacity() << endl;
 cout << s << endl;
 // 将s中有效字符个数缩小到5个
 s.resize(5);
 cout << s.size() << endl;
 cout << s.capacity() << endl;
 cout << s << endl;
}
//==============================================================================
void Teststring2()
{
 string s;
 // 测试reserve是否会改变string中有效元素个数
 s.reserve(100);
 cout << s.size() << endl;
 cout << s.capacity() << endl;
 // 测试reserve参数小于string的底层空间大小时,是否会将空间缩小
 s.reserve(50);
 cout << s.size() << endl;
 cout << s.capacity() << endl;
}
// 利用reserve提高插入数据的效率,避免增容带来的开销
//==============================================================================
void TestPushBack()
{
 string s;
 size_t sz = s.capacity();
 cout << "making s grow:\n";
 for (int i = 0; i < 100; ++i)
 {
 s.push_back('c');
 if (sz != s.capacity())
 {
 sz = s.capacity();
 cout << "capacity changed: " << sz << '\n';
 }
 }
}
void TestPushBackReserve()
{
 string s;
 s.reserve(100);
 size_t sz = s.capacity();
 
 cout << "making s grow:\n";
 for (int i = 0; i < 100; ++i)
 {
 s.push_back('c');
 if (sz != s.capacity())
 {
 sz = s.capacity();
 cout << "capacity changed: " << sz << '\n';
 }
 }
}

【注意】

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

  1. clear()只是将string中有效字符清空,不改变底层空间大小。

  1. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

  1. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

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

函数名称

功能说明

operator[]

返回pos位置的字符,const string类对象调用

begin+end

begin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器

rbegin+rend

begin获取一个字符的迭代器+end获取最后一个字符下一个位置的迭代器

范围for

C++11支持更简洁的范围for的新遍历方式

void Teststring()
{
 string s1("hello Bit");
 const string s2("Hello Bit");
 cout<<s1<<" "<<s2<<endl;
 cout<<s1[0]<<" "<<s2[0]<<endl;
 
 s1[0] = 'H';
 cout<<s1<<endl;
 
 // s2[0] = 'h'; 代码编译失败,因为const类型对象不能修改
}
void Teststring()
{
 string s("hello Bit");
 // 3种遍历方式:
 // 需要注意的以下三种方式除了遍历string对象,还可以遍历是修改string中的字符,
 // 另外以下三种方式对于string而言,第一种使用最多
 // 1. for+operator[]
 for(size_t i = 0; i < s.size(); ++i)
 cout<<s[i]<<endl;
 
 // 2.迭代器
 string::iterator it = s.begin();
 while(it != s.end())
 {
 cout<<*it<<endl;
 ++it;
 }
 
 string::reverse_iterator rit = s.rbegin();
 while(rit != s.rend())
 cout<<*rit<<endl;
 
 // 3.范围for
 for(auto ch : s)
 cout<<ch<<endl;
}

string类对象的修改操作

函数名称

功能说明

push_back

在字符串后尾插字符c

append

在字符串后追加一个字符串

operator+=

在字符串后追加字符串str

c_str

返回C格式的字符串

find+npos

从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置

rfind

从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置

substr

在str中从pos位置开始,截取n个字符,然后将其返回

void Teststring()
{
 string str;
 str.push_back(' '); // 在str后插入空格
 str.append("hello"); // 在str后追加一个字符"hello"
 str += 'b'; // 在str后追加一个字符'b' 
 str += "it"; // 在str后追加一个字符串"it"
 cout<<str<<endl;
 cout<<str.c_str()<<endl; // 以C语言的方式打印字符串
 
 // 获取file的后缀
 string file1("string.cpp");
 size_t pos = file.rfind('.');
 string suffix(file.substr(pos, file.size()-pos));
 cout << suffix << endl;
 
 // npos是string里面的一个静态成员变量
 // static const size_t npos = -1;
 
 // 取出url中的域名
 sring url("http://www.cplusplus.com/reference/string/string/find/");
 cout << url << endl;
 size_t start = url.find("://");
 if (start == string::npos)
 {
 cout << "invalid url" << endl;
 return;
 }
 start += 3;
 size_t finish = url.find('/', start);
 string address = url.substr(start, finish - start);
 cout << address << endl;
 
 // 删除url的协议前缀
 pos = url.find("://");
 url.erase(0, pos+3);
 cout<<url<<endl;
}

【注意】

  1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

  1. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

string类非成员函数

函数

功能说明

operator+

尽量少用,因为传值返回,导致深拷贝效率低下

operator>>

输入运算符重载

operator<<

输出运算符重载

getline

获取一行字符串

relational operators

大小比较

运用

  • 仅仅反转字母

class Solution {
public:
 string reverseOnlyLetters(string S) {
 char* pLeft = (char*)S.c_str();
 char* pRight = pLeft + (S.size()-1);
 while(pLeft < pRight)
 {
 // 从前往后找,找到一个字母
 while(pLeft < pRight)
 {
 // 找到有效字母后停下来
 if(isalpha(*pLeft))
 break;
 
 ++pLeft;
 }
 // 从后往前找,找一个字母
 while(pLeft < pRight)
 {
 // 找到有效字母后停下来
 if(isalpha(*pRight))
 break;
 
 --pRight;
 }
 if(pLeft < pRight)
 {
 swap(*pLeft, *pRight);
 ++pLeft;
 --pRight;
 }
 }
 return S;
 }
};
  • 找字符串中第一个只出现一次的字符

class Solution {
public:
 int firstUniqChar(string s) {
 
 // 统计每个字符出现的次数
 int count[256] = {0};
 int size = s.size();
 for(int i = 0; i < size; ++i)
 count[s[i]] += 1;
 
 // 按照字符次序从前往后找只出现一次的字符
 for(int i = 0; i < size; ++i)
 if(1 == count[s[i]])
 return i;
 
 return -1;
 }
};
  • 字符串里面最后一个单词的长度

#include<iostream>
#include<string>
using namespace std;
int main()
{
 string line;
 // 不要使用cin>>line,因为会它遇到空格就结束了
 // while(cin>>line)
 while(getline(cin, line))
 {
 size_t pos = line.rfind(' ');
 cout<<line.size()-pos-1<<endl;
 }
 return 0;
}
  • 验证一个字符串是否回文

class Solution {
public:
 bool isLetterOrNumber(char ch)
 {
 return (ch >= '0' && ch <= '9')
 || (ch >= 'a' && ch <= 'z')
 || (ch >= 'A' && ch <= 'Z');
 }
 
 bool isPalindrome(string s) {
 // 先小写字母转换成大写,再进行判断
 for(auto& ch : s)
 {
 if(ch >= 'a' && ch <= 'z')
 ch -= 32;
 }
 
 int begin = 0, end = s.size()-1;
 while(begin < end)
 {
 while(begin < end && !isLetterOrNumber(s[begin]))
 ++begin;
 
 while(begin < end && !isLetterOrNumber(s[end]))
 --end;
 
 if(s[begin] != s[end])
 {
 return false;
 }
 else
 {
 
 ++begin;
 --end;
 }
 }
 
 return true;
 }
};
  • 字符串相加

class Solution {
public:
 string addstrings(string num1, string num2) 
 {
 // 从后往前相加,相加的结果到字符串可以使用insert头插
 // 或者+=尾插以后再reverse过来
 int end1 = num1.size()-1;
 int end2 = num2.size()-1;
 int value1 = 0, value2 = 0, next = 0;
 string addret;
 while(end1 >= 0 || end2 >= 0)
 {
 if(end1 >= 0)
 value1 = num1[end1--]-'0';
 else
 value1 = 0;
 
 if(end2 >= 0)
 value2 = num2[end2--]-'0';
 else
 value2 = 0;
 
 int valueret = value1 + value2 + next;
 if(valueret > 9)
 {
 next = 1;
 valueret -= 10;
 }
 else
 {
 next = 0;
 }
 
 //addret.insert(addret.begin(), valueret+'0');
 addret += (valueret+'0');
 }
 
 if(next == 1)
 {
 //addret.insert(addret.begin(), '1');
 addret += '1';
 }
 
 reverse(addret.begin(), addret.end());
 return addret;
 }
};

string类的模拟实现

namespace bit
{
 class string
 {
 public:
 typedef char* iterator;
 public:
 string(const char* str = "")
 {
 _size = strlen(str);
 _capacity = _size;
 _str = new char[_capacity+1];
 strcpy(_str, str);
 }
 string(const string& s)
 : _str(nullptr)
 , _size(0)
 , _capacity(0)
 {
 string tmp(s);
 this->Swap(tmp);
 }
 string& operator=(string s)
 {
 this->Swap(s)
 return *this;
 }
 ~string()
 {
 if (_str)
 {
 delete[] _str;
 _str = nullptr;
 }
 }
 /
 // iterator
 iterator begin() {return _str;}
 iterator end(){return _str + _size;}
 /
 // modify
 void push_back(char c)
 {
 if (_size == _capacity)
 Reserve(_capacity*2);
 
 _str[_size++] = c;
 _str[_size] = '\0';
 }
 string& operator+=(char c)
 {
 PushBack(c);
 return *this;
 }
 
 // 作业实现
 void append(const char* str);
 string& operator+=(const char* str); 
 void clear()
 {
 _size = 0;
 _str[_size] = '\0';
 }
 void swap(string& s)
 {
 swap(_str, s._str);
 swap(_size, s._size);
 swap(_capacity, s._capacity);
 }
 const char* c_str()const
 {
 return _str;
 }
 /
 // capacity
 size_t size()const
 size_t capacity()const
 bool empty()const
 
 void resize(size_t newSize, char c = '\0')
 {
 if (newSize > _size)
 {
 // 如果newSize大于底层空间大小,则需要重新开辟空间
 if (newSize > _capacity)
 {
 Reserve(newSize);
 }
 memset(_str + _size, c, newSize - _size);
 }
 _size = newSize;
 _str[newSize] = '\0';
 }
 void reserve(size_t newCapacity)
 {
 // 如果新容量大于旧容量,则开辟空间
 if (newCapacity > _capacity)
 {
 char* str = new char[newCapacity + 1];
 strcpy(str, _str);
 // 释放原来旧空间,然后使用新空间
 delete[] _str;
 _str = str;
 _capacity = newCapacity;
 }
 }
 
 // access
 char& operator[](size_t index)
 {
 assert(index < _size);
 return _str[index];
 }
 const char& operator[](size_t index)const
 {
 assert(index < _size);
 return _str[index];
 }
 
 // 作业
 bool operator<(const string& s);
 bool operator<=(const string& s);
 bool operator>(const string& s);
 bool operator>=(const string& s);
 bool operator==(const string& s);
 bool operator!=(const string& s);
 // 返回c在string中第一次出现的位置
 size_t find (char c, size_t pos = 0) const;
 // 返回子串s在string中第一次出现的位置
 size_t find (const char* s, size_t pos = 0) const;
 
 // 在pos位置上插入字符c/字符串str,并返回该字符的位置
 string& insert(size_t pos, char c);
 string& insert(size_t pos, const char* str);
 // 删除pos位置上的元素,并返回该元素的下一个位置
 string& erase(size_t pos, size_t len);
 private:
 friend ostream& operator<<(ostream& _cout, const bit::string& s);
 friend istream& operator>>(istream& _cin, bit::string& s);
 private:
 char* _str;
 size_t _capacity;
 size_t _size;
 };
}
ostream& bit::operator<<(ostream& _cout, const bit::string& s)
{
 // 不能使用这个
 //cout << s._str;
 for(size_t i = 0; i < s.size(); ++i)
 {
 _cout<<s[i];
 }
 return _cout;
}
///对自定义的string类进行测试
void TestBitstring()
{
 bit::string s1("hello");
 s1.push_back(' ');
 s1.push_back('b');
 s1.append(1, 'i');
 s1 += 't';
 cout << s1 << endl;
 cout << s1.size() << endl;
 cout << s1.capacity() << endl;
 // 利用迭代器打印string中的元素
 string::iterator it = s1.begin();
 while (it != s1.end())
 {
 cout << *it<<" ";
 ++it;
 }
 cout << endl;
 
 // 这里可以看到一个类只要支持的基本的iterator,就支持范围for
 for(auto ch : s1)
 cout<<ch<<" ";
 cout<<endl;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2D图像处理:九点标定_上(机械手轴线与法兰轴线重合)(附源码)

文章目录 1. 九点标定2. 九点标定流程2.1 机械手轴线与法兰轴线重合代码实现1. 九点标定 在2D视觉抓取项目中,如果想要让机械手准确的抓取到工件,前提是需要知道机械手应该移动到哪里(位姿)。而移动到哪里(位姿)的获取就需要对相机和机械手进行标定。因此,九点标定(2D视…

ESP32设备驱动-MAX6675冷端补偿K热电偶数字转换器

MAX6675冷端补偿K热电偶数字转换器 1、MAX6675介绍 MAX6675执行冷端补偿并将来自K型热电偶的信号数字化。 数据以 12 位分辨率、SPI™ 兼容的只读格式输出。 该转换器可将温度解析为 0.25C,读数高达 +1024C,并且在 0C 至 +700C 的温度范围内具有 8 LSB 的热电偶精度。 MAX…

力扣旋转字符串

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:介绍字符串旋转,左旋,右旋即旋转结果. 金句分享: ✨好好干&…

如何通过Java将Word转换为PDF

Word是我们日常编辑文档内容时十分常用的一种文档格式。但相比之下&#xff0c;PDF文档的格式、布局更为固定&#xff0c;不易被更改。在保存或传输较为重要的文档内容时&#xff0c;PDF文档格式也时很多人的不二选择。很多时候我们都会遇到需要将Word转换为PDF的情况。下面我就…

放弃node-sass,启用sass

在下载一个新项目时运行&#xff1a;npm run install 发现报错 npm uninstall 异常 Error: Could not find any Visual Studio installation to use 或是 ------------------------- You need to install the latest version of Visual Studio npm ERR! gyp ERR! find VS incl…

嵌入式Linux(二十四)系统烧写

将uboot&#xff0c;linux kernel&#xff0c;.dtb&#xff0c;rootfs烧写到板子上的EMMC上&#xff0c;避免断网导致不能运行。 1. MfgTool工具介绍 一路解压之后&#xff0c;得到以下两项&#xff1a; ①Profiles文件夹&#xff1a;后续烧写文件放到这个文件夹。  其中关注…

宝塔+docker+jenkins部署vue项目(保姆级教程)

1.使用宝塔安装docker 在软件商城安装Docker管理器 2.使用docker下载jenkins镜像 使用命令行 docker pull jenkins/jenkins:lts //lts表示支持版本较长3.创建并且挂载jenkins目录并赋值 jenkins_home为我创建的目录 可以修改任意目录 mkdir -p /jenkins_home cho…

pytest测试框架——allure报告

文章目录一、allure的介绍二、allure的运行方式三、allure报告的生成方式一、在线报告、会直接打开默认浏览器展示当前报告方式二、静态资源文件报告&#xff08;带index.html、css、js等文件&#xff09;&#xff0c;需要将报告布置到web服务器上。四、allure中装饰器1、实现给…

【LeetCode每日一题:982. 按位与为零的三元组+从递归超时到记忆化搜索】

题目描述 给你一个整数数组 nums &#xff0c;返回其中 按位与三元组 的数目。 按位与三元组 是由下标 (i, j, k) 组成的三元组&#xff0c;并满足下述全部条件&#xff1a; 0 < i < nums.length 0 < j < nums.length 0 < k < nums.length nums[i] & …

Common API环境部署(保姆级教程,填充了很多坑)

Common API环境部署目录一、前言及结果展示二、Windows下安装docker1. 准备工作[1.1 Docker安装包](https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe)[1.2 Wsl2安装包](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.ms…

【数据结构】链式二叉树

前言 在前面我们学习了一些二叉树的基本知识&#xff0c;了解了它的结构以及一些性质&#xff0c;我们还用数组来模拟二叉树建立了堆&#xff0c;并学习了堆排序&#xff0c;可是数组结构的二叉树有很大的局限性&#xff0c;平常我们用的最多树结构的还是链式二叉树&#xff0c…

【自律】学习方案

自律来源 轶事 陆奇以精力旺盛著称&#xff0c;通常凌晨4点起床&#xff0c;先查邮件&#xff0c;然后在跑步机上跑4英里&#xff0c;边跑边听古典音乐或看新闻。早上5点至6点至办公室&#xff0c;利用这段时间不受别人干扰准备一天的工作&#xff0c;然后一直工作到晚上10点&a…

搜索引擎的设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;随着互联网的快速发展&#xff0c;网络上的数据也随着爆炸式地增长。如何最快速筛选出对我们有用的信息成了主要问题。搜索引擎是指根据一定的策略、运用特定的计算机程序从互联网上搜集信息&#xff0c;在对信息进行组织和处理后&…

ks通过恶意低绩效来变相裁员(五)绩效申诉就是「小六自证吃了一碗凉粉」

目录 一、小六吃了一碗凉粉 二、给你差绩效 公司告诉你可以绩效申诉 1、公司的实际目的是啥 2、你一旦自证&#xff0c;就掉入了陷阱 三、谁主张谁举证——让公司证明它绩效考核的客观性和公平性 四、针对公司的流氓恶意绩效行为&#xff0c;还有其他招吗 五、当公司用各…

学习方法--找书,背书,利器

学习方法 前言&#xff1a; 1、所谓的技术/技能&#xff0c;可比作对一类书的学习&#xff0c;那么第一步&#xff0c;就是要找这方面的书本来学习&#xff0c;简称为“找书”&#xff0c;找书既是指资料&#xff0c;也是指经验总结等等&#xff0c;第二步&#xff0c;就是背下…

【基础算法】双指针---数组元素的目标和

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

CSS 基础:选择器、盒模型、布局

CSS&#xff08;Cascading Style Sheets&#xff09;是用于定义 HTML 或 XML 文档中的样式的一种语言。它可以控制网页的排版、字体、颜色、背景等多个方面&#xff0c;从而使网页呈现出美观的视觉效果和良好的用户体验。其中&#xff0c;选择器、盒模型和布局是 CSS 基础中的三…

Pod控制器

一.Pod控制器及其功用Pod控制器&#xff0c;又称之为工作负载&#xff08;workload&#xff09;&#xff0c;是用于实现管理pod的中间层&#xff0c;确保pod资源符合预期的状态&#xff0c;pod的资源出现故障时&#xff0c;会尝试进行重启&#xff0c;当根据重启策略无效&#…

C. Zero Path

给你一个矩阵&#xff0c;矩阵中每个点是1或者-1&#xff0c;问你是否存在一条路径从左上角到右下角路径上所经过点的总和是0。 类似于数字三角型&#xff0c;dp[i][j]可以用dp[i-1][j]的位置 和 dp[i][j-1]的位置传递过来&#xff0c;我们可以保存每个位置可以达成的和的所有可…

ROS小车研究笔记3/4/2023:自动导航launch文件解析

对于ROS小车导航算法基本原理和使用方法&#xff0c;可以看笔记http://t.csdn.cn/NUWHt 1 启动小车导航节点&#xff1a;turn_on_wheeltec_robot navigation.launch <launch><!-- 开启机器人底层相关节点 同时开启导航功能--><include file"$(find turn_on…