【STL】string

头文件:

#include<string>

string的基本概念概念:

概念:string是c++中的字符串类型,相当于C语言中的char *,其本质是一个封装好的类

stringchar*的区别:

  • char* 是一个指针
  • string是一个内部封装了char* 的类,用来管理这个字符串,是一个char*型容器
  • char*为静态存储,大小被固定
  • string为动态存储(但是在堆和栈中都存有)

特点:

  • string类内部封装了很多成员函数
    例如:查找find,拷贝copy,删除delete,替换replace,插入insert
  • string管理char*所分配的内存,不用担心赋值越界和取值越界等问题,由类内部负责

string的构造函数

函数原型:

  1. string(); 默认构造,创建一个空字符串
  2. string(const char* s); 使用字符串初始化
  3. string(const string& str); 拷贝构造,使用一个string对象初始化另一个string对象
  4. string(int n,char c); 使用n个字符c初始化

实例:

#include<iostream>
using namespace std;
int main()
{string str1;             //1string str21("aaaaa");   //2string str22="bbbbb";string str3(str21);      //3string str4(5, 'c');     //4cout << "str21=" << str21 <<"\nstr22=" << str22 << "\nstr3=" << str3 << "\nstr4=" << str4 << endl;return 0;
}

运行结果:

str21=aaaaa
str22=bbbbb
str3=aaaaa
str4=ccccc

string的赋值操作

函数原型:

  1. string& operator=(const char* s); char* 类型字符串赋给当前字符串
  2. string& operator=(const string& str); string类型字符串str赋给当前字符串
  3. string& operator=(char c); 单个字符赋给当前字符串
  4. string& assign(const char* s); char类型字符串赋给当前字符串
  5. string& assign(const char* s,int n); 把字符串s前n个字符赋给当前字符串
  6. string& assign(const string& str); string类型字符串str赋给当前字符串
  7. string& assign(int n,char c); 把n个字符c赋给当前字符串

实例:

#include<iostream>
using namespace std;
int main()
{string str[7];str[0] = "aaaaa";              //1str[1] = str[0];               //2str[2] = 'a';                  //3str[3].assign("bbbbb");        //4str[4].assign("ccccc", 3);     //5str[5].assign(str[4]);         //6str[6].assign(5, 'd');         //7cout << "\nstr[0]=" << str[0] << "\nstr[1]=" << str[1] << "\nstr[2]=" << str[2] << "\nstr[3]=" << str[3]<< "\nstr[4]=" << str[4] << "\nstr[5]=" << str[5] << "\nstr[6]=" << str[6] << endl;cout << "str[0][0]=" << str[0][0] << endl;return 0;
}

运行结果:

str[0]=aaaaa
str[1]=aaaaa
str[2]=a
str[3]=bbbbb
str[4]=ccc
str[5]=ccc
str[6]=ddddd
str[0][0]=a

string字符串的拼接

函数原型:

  1. string& operator+=(const char* s); 重载+=
  2. string& operator+=(const char c);
  3. string& operator+=(const string& str);
  4. string& append(const char* s); 把字符串s连接到当前字符串尾
  5. string& append(const char* s,int n); 把字符串s前n个字符连接到当前字符串尾
  6. string& append(const string& str);
  7. string& append(const string& str,int pos,int n); 把字符串str从pos开始的n个字符连接到当前字符串尾

实例:

#include<iostream>
using namespace std;
int main()
{string str1;string str2 = " C++";string str3 = " ,yesssssss";str1 += 'I';                               //2,str1 += " love";                           //1str1 += str2;                              //3str1.append(" and");                       //4str1.append(" algorithm aaa",10);          //5str1.append(str3);                         //6str1.append(str3, 0, 5);                   //7cout << str1;return 0;
}

运行结果:

I love C++ and algorithm ,yesssssss ,yes

string查找与替换

  • 查找函数findrfind,功能是查找指定字符串是否存在,若存在返回出现的下标位置,若不存在返回-1
  • 替换函数replace在指定位置替换字符串中某些字符

函数原型:

  1. int find(const string& str,int pos = 0);从pos开始查找字符串str第一次出现的位置
    使用:int num = str1.find(str2,pos);以下几个使用类似
  2. int find(const char* s,int pos=0); 从pos开始查找字符串s第一次出现的位置
  3. int find(const string& str,int pos = 0,int n);从pos开始查找字符串str的前n个字符第一次出现的位置
  4. int find(const char c,int pos=0); 从pos开始查找字符c第一次出现的位置
  5. int rfind(const string& str,int pos = npos);从pos开始查找字符串str最后一次出现的位置
  6. int rfind(const char* s, int pos = npos); 从pos开始查找字符串s最后一次出现的位置
  7. int rfind(const string& str,int pos,int n);从pos开始查找字符串str的前n个字符最后一次出现的位置
  8. int rfind(const char c,int pos=0); 从pos开始查找字符c最后一次出现的位置
  9. string& replace(int pos,int n,const string& str);用字符串str替换从pos开始的n个字符
    使用: str1.replace(pos,n,str2);
  10. string& replace(int pos,int n,const char* s);用字符串s替换从pos开始的n个字符

实例:

#include<iostream>
using namespace std;
int main()
{string str1 = "abcdEabcdef";int pos = str1.find("cd");if (pos != -1){cout << "pos=" << pos << endl;}else cout << "未找到" << endl;pos = str1.rfind("cd");if (pos != -1){cout << "pos=" << pos << endl;}else cout << "未找到" << endl;str1.replace(2, 3, "1234");//用"1234"替换从第二个位置开始的3个字符cout << str1 << endl;return 0;
}

运行结果:

pos=2
pos=7
ab1234abcdef

string的比较

比较方式:
字符串之间的比较是逐个字符按照ASCII码大小进行比较的,调用str1.compare(str2)成员函数。

函数原型:

  • int compare(const string& str);与字符串str比较
  • int compare(const char* s);与字符串s比较

当两个字符串相等时(即字符串完全相同)函数返回 0 ;
当str1大于str2时函数返回 1;
当str1小于str2时函数返回 -1;

特别地,判断两个string类字符串的大小还可以使用重载的运算符 ==、!=、>、<、>=、<= 进行比较。
如:str1 == str2、str1 > str2、str1 <= str2等

实例:

#include<iostream>
using namespace std;
int main()
{string str1 = "abcdefg";string str2 = "bcdef";if (str1.compare(str2) == 0)//或者使用 str1==str2cout << "字符串相等\n";else if (str1.compare(str2) > 0)//或者使用 str1 > str2cout << "str1较大\n";elsecout << "str1较小\n";if (str1.compare("abcdefg") == 0)cout << "字符串相等\n";else if (str1.compare("abcdefg") > 0)cout << "str1较大\n";elsecout << "str1较小\n";return 0;
}

运行结果:

str1较小
字符串相等

string的存取

字符串的存取即 string中单个字符的访问与修改

函数原型:

  1. char& operator[](int n) 通过[]方式访问与修改字符
  2. char& at(int n) 通过at方式获取字符

实例:

#include<iostream>
using namespace std;
int main()
{string str = "abcde";for (int i = 0; i < str.size(); ++i) //size() 是获取字符串大小的函数{str[i] = 'A'+i;           //通过[]方式修改cout << str[i] << " ";    //通过[]方式访问}cout << endl;for (int i = 0; i < str.size(); ++i) {str.at(i) = 'a' + i;          //通过at方式修改cout << str.at(i) << " ";     //通过at方式访问}return 0;
}

运行结果:

A B C D E
a b c d e

string的插入和删除

函数原型:

  1. string& insert(int pos,const char* s); 从pos位置开始插入字符串s,pos均从0开始计数
  2. string& insert(int pos,const string& str); 从pos位置开始插入字符串str
  3. string& insert(int pos,int n,char c); 从pos位置开始插入n个字符c
  4. string& erase(int pos,int n=npos); 从pos位置开始删除n个字符

实例:

#include<iostream>
using namespace std;
int main()
{string str = "hello";str.insert(2, "123");cout << "插入后:" << str << endl;str.erase(2,3);cout << "删除后:" << str << endl;return 0;
}

运行结果:

插入后:he123llo
删除后:hello

string类对象的容量操作

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

实例1:

#include<iostream>
using namespace std;
int main()
{string s1("bit education");string s2("C++");cout << s1.size() << endl;cout << s2.size() << endl;cout << s1.length() << endl;cout << s2.length() << endl;//在C++中size函数与length函数等同cout << s1.max_size() << endl;cout << s2.max_size() << endl;cout << s1.capacity() << endl;cout << s2.capacity() << endl;s1.clear();                  cout << s1.size() << endl;//size减为0			 cout << s1.capacity() << endl;//capacity空间依旧保留return 0;
}

运行结果:

13
3
13
3
4611686018427387897
4611686018427387897
13
3
0
13

实例2:使用reserve函数进行容量操作:

  1. reserve()函数并不改变字符串的实际长度,也不会初始化新增的内存区域,只是为将来的添加操作预留了足够的内存空间。
  2. 若reserve函数分配的内存小于字符串当前的内存实际上并不会改变当前字符串的内存大小

未使用reserve的情况下:

#include<iostream>
using namespace std;
int main()
{string s;size_t sz = s.capacity();cout << "making s grow:" << endl;for (size_t i = 0; i < 100; i++){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed:" << sz << endl;}}return 0;
}

运行结果:字符串每达到一定大小后就会扩容

making s grow:
capacity changed:1
capacity changed:2
capacity changed:4
capacity changed:8
capacity changed:16
capacity changed:32
capacity changed:64
capacity changed:128

使用reserve的情况下:

#include<iostream>
using namespace std;
int main()
{string s;s.reserve(100);size_t sz = s.capacity();cout << "making s grow:" << endl;for (size_t i = 0; i < 100; i++){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed:" << sz << endl;}}return 0;
}

运行结果:字符串沿着reserve预留空间增长,没有扩容

making s grow:

实例3:使用resize函数进行容量操作

  1. 若调用 resize 函数时指定的大小小于当前字符串的大小,则 resize() 函数会截断当前字符串,使其大小等于指定的大小。这时,被截断的部分字符会被删除,内部存储区域的大小也会被缩小到刚好能够容纳截断后的字符串。
  2. 当内存重新分配时,会将原有的字符串内容复制到新的存储区域中。因此,如果 resize() 函数调整了内部存储区域的大小,则该函数的时间复杂度是O(len),其中len是当前字符串的大小。
  3. resize函数重新分配的内存区域,新增的部分会被初始化。
#include<iostream>
using namespace std;
int main()
{string s;s.resize(90);size_t sz = s.capacity();cout << "making s grow:" << endl;for (size_t i = 0; i < 100; i++){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed:" << sz << endl;}}return 0;
}

运行结果:由于新增区域被初始化,push_back函数会在初始化之后的地方开始尾增

making s grow:
capacity changed:180
capacity changed:360

string类对象的遍历操作

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

[下标]遍历

#include<iostream>
using namespace std;
int main ()
{std::string str ("Test string");for (int i=0; i<str.length(); ++i){std::cout << str[i];}return 0;
}

迭代器

对于 std::string 的迭代器来说,它支持随机访问,因此可以像指针那样进行指针算术运算。例如:使用 it += 1 或 it -= 1 来移动迭代器的位置。因此,如果只是移动迭代器一个位置,使用指针算术运算比使用 std::advance 函数更加方便和高效。

不过需要注意的是,并非所有的迭代器都支持随机访问。对于某些容器(例如 std::list),其迭代器只支持前向迭代,不支持随机访问和指针算术运算,此时就需要使用 std::advance 函数来移动迭代器的位置。因此,在编写代码时,需要根据具体情况选择合适的方法来移动迭代器。

实例:

#include<iostream>
using namespace std;
int main()
{string s1("bit education");string::iterator it = s1.begin();//auto it=s1.begin();auto自动推导it是迭代器//读取while (it != s1.end()){cout << *it << " ";it++;}cout << endl;//写入it = s1.begin();while (it != s1.end()){*it = *it + 2;it++;}cout << s1 << endl;return 0;
}

运行结果:

b i t   e d u c a t i o n
dkv"gfwecvkqp

基于范围的for循环

#include<iostream>
using namespace std;
int main()    //范围for的遍历 C++11原理是迭代器
{string s1("Hello World!");for (auto s : s1)   //依次取出容器s1里面的字符给s{cout << s << " ";}cout << endl;for (auto s : s1){s = s + 1;cout << s << " ";}cout << endl;return 0;
}

运行结果:

H e l l o   W o r l d !
I f m m p ! X p s m e "

反向迭代器

  • 反向迭代器(reverse iterator)是一种能够以相反的顺序遍历容器元素的迭代器,即从最后一个元素开始遍历,一直到第一个元素。C++ 标准库中提供了 std::reverse_iterator 类来实现反向迭代器。
  • std::reverse_iterator 是一个适配器类,它将一个普通的迭代器包装成反向迭代器。
  • 通过调用std::make_reverse_iterator 函数可以将一个正向迭代器包装成反向迭代器。
#include<iostream>
using namespace std;
int main()    //反向迭代器,倒着遍历
{string s1("bit education");string::reverse_iterator rit = s1.rbegin();while (rit != s1.rend()){cout << *rit << " ";rit++;}cout << endl;return 0;
}

const修饰的迭代器

#include<iostream>
#include<typeinfo>
using namespace std;
//将字符串数字转化为整形
int StringInt(const string& str)
{int result = 0;string::const_iterator it = str.begin();while(it != str.end()){result = result * 10 + (*it - '0');it++;}return result;
}
int main()
{string s("123456");cout << StringInt(s) << endl;cout << typeid(StringInt(s)).name() <<endl;return 0;
}

运行结果:

123456
i

在C++中,可以使用 typeid运算符来获取一个表达式的类型信息。具体来说,可以使用 typeid(expression)来获取 expression的类型信息,返回值是一个 std::type_info类型的对象,可以通过其 name()成员函数来获取类型的名称。

实例:

#include <iostream>
#include <typeinfo>void foo(int x, double y, const char* z) {std::cout << "x: " << typeid(x).name() << std::endl;std::cout << "y: " << typeid(y).name() << std::endl;std::cout << "z: " << typeid(z).name() << std::endl;
}int main() {foo(42, 3.14, "hello");return 0;
}

运行结果:

x: i
y: d
z: PKc

其中,i表示int类型,d表示double类型,PKc表示const char*类型。需要注意的是,typeid返回的类型名称可能是编译器特定的,不同编译器可能会有不同的实现。

此段来源于:https://blog.csdn.net/Dontla/article/details/130457108


string的子串

函数原型:

string substr(int pos,int n=npos);

返回由pos开始的n个字符组成的子串,默认的npos是从pos到字符串结尾的所有字符的个数

  • s.substr(); 返回s的全部内容
  • s.substr(11); 从索引11往后的子串
  • s.substr(5,6); 从索引5开始6个字符

实例:

#include<iostream>
using namespace std;
int main()
{//获取QQ邮箱前面的QQ号string str = "123456789@qq.com";int pos = str.find("@");string QQnumb = str.substr(0, pos);cout << "邮箱为:" << str << endl;cout << "QQ号为:" << QQnumb << endl;return 0;
}

运行结果:

邮箱为:123456789@qq.com
QQ号为:123456789

C字符串、string串、stringstream之间的关系

首先必须了解,string可以被看成是以字符为元素的一种容器。字符构成序列(字符串)。有时候在字符序列中进行遍历,标准的string类提供了STL容器接口。具有一些成员函数比如begin()、end(),迭代器可以根据他们进行定位。注意,与char不同的是,string不一定以NULL(‘\0’)结束。string长度可以根据length()得到,string可以根据下标访问。所以,不能将string直接赋值给char

string转换成const char *

如果要将字面值string直接转换成const char *类型,string有2个函数可以运用:一个是.c_str(),一个是data成员函数。
c_str()函数返回一个指向正规C字符串的指针,内容与本string串相同。这是为了与C语言兼容,在C语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成C中的字符串样式。注意:一定要使用strcpy()函数等来操作方法c_str()返回的指针

string str = "Hello World";
const char *ch1 = str.c_str();
const char *ch2 = str.data();

此时,ch1与ch2的内容将都是”Hello World”。但是只能转换成const char*,如果去掉const编译不能通过。

string转换成char *

C++提供的由C++字符串得到对应的C_string的方法是使用data()、c_str()和copy(),其中

  1. data()以字符数组的形式返回字符串内容,但并不添加’\0’。
  2. c_str()返回一个以’\0’结尾的字符数组,返回值是const char*
  3. copy()则把字符串的内容复制或写入既有的c_string或字符数组内。

C++字符串并不以’\0’结尾。我的建议是在程序中能使用C++字符串就使用,除非万不得已不选用c_string。
如果要转换成char*,可以用string的一个成员函数strcpy实现。

string str = "Hello World";
int len = str.length();
char *data = new char[len+1];  //这里+1还是不+1需要注意
strcpy(data, str.c_str());  // const char *data = new char[len+1];  strcpy(data, str);

此时,data中的内容为”Hello World”使用c_str()要么str赋给一个const指针,要么用strcpy()复制。

char *转换成string

string类型能够自动将C风格的字符串转换成string对象:

string str; 
const char *pc = "Hello World"; 
str = pc;
printf(“%s\n”, str);  //此处出现错误的输出
cout<<str<<endl;

不过这个是会出现问题的。有一种情况我要说明一下。当我们定义了一个string类型之后,用printf(“%s”,str);输出是会出问题的。这是因为“%s”要求后面的对象的首地址。但是string不是这样的一个类型。所以肯定出错。
用cout输出是没有问题的,若一定要printf输出。那么可以这样:

printf("%s",str.c_str());

char[ ] 转换成string

这个与char*的情况相同,也可以直接赋值,但是也会出现上面的问题,需要同样的处理。

字符数组转化成string类型:

char ch [] = "ABCDEFG";
string str(ch); //也可string str = ch;

或者

char ch [] = "ABCDEFG";
string str;
str = ch; //在原有基础上添加可以用str += ch;

string转换成char[ ]

string对象转换成C风格的字符串:

const char *str = s.c_str();

这是因为为了防止字符数组被程序直接处理c_str()返回了一个指向常量数组的指针。
由于我们知道string的长度可以根据length()函数得到,又可以根据下标直接访问,所以用一个循环就可以赋值了,这样的转换不可以直接赋值。

string str = "Hello World";
int len=str.length();
char ch[255]={};
for( int i=0;i<str.length();i++)
ch[i] = str[i];
ch[len+1] = '\0';
printf("%s\n", ch);
cout<<ch<<endl;

stringstream与string间的绑定

stringstream strm;
string s;
strm<<s;  // 将s写入到strm
strm>>s;  // 从strm读取串写入s
strm.str(); // 返回strm中存储的string类型对象
strm.str(s); // 将string类型的s复制给strm 返回void
char* cstr;  // 将C字符数组转换成流
string str(cstr);
stringstream ss(str);

详细了解stringstream请看:【C++】stringstream

参考博文:

https://blog.csdn.net/qq_52324409/article/details/121404001

https://blog.csdn.net/qq947467490/article/details/130183703

https://blog.csdn.net/soinlove36/article/details/119796794

https://blog.csdn.net/hero_myself/article/details/52313617

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

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

相关文章

uniapp小程序给指定的页面新增下拉刷新功能

需求:有些页面需要实时更新数据,但是又不能做实时刷新,所以给用户一个手动下拉刷新指定接口的功能 第一步:在pages.json给页面加"enablePullDownRefresh": true配置 第二步:在指定页面写onPullDownRefresh方法,和methods同级 onPullDownRefresh() {//加个定时器1秒…

辉芒微FMD之FT61EC2x

辉芒微的官网&#xff1a;辉芒微电子 FMD | 官方网站 (fremontmicro.com) 1、安装开发环境 一共有如下三款APP&#xff0c; 第一个是 FMDIDE&#xff1b; FMDIDE软件是支持全系列8位MCU的集成开发环境&#xff0c;集代码编辑、分析、编译、调试等功能于一身。 编译器支持C89…

融中财经专访 | 欧科云链:从跟随行业到引领行业

导读 THECAPITAL 新行业中的经验“老兵”。 本文4089字&#xff0c;约5.8分钟 作者 | 吕敬之 编辑 | 吾人 来源 | 融中财经 &#xff08;ID&#xff1a;thecapital&#xff09; 一个新兴行业从发展到成熟需要几个必要的推手&#xff1a;人才、产品、制度。 Web3.0&…

Github第一Star数的国产免费开源防火墙--雷池社区版初步体验

前言 近期准备搭建一个博客网站&#xff0c;用来存储工作室同学们的学习笔记。服务器准备直接放在公网上&#xff0c;方便大家随时随地的上传和浏览&#xff0c;为了防止网站被人日穿成为肉鸡&#xff0c;一些防御措施还是要部署的。 首先明确自己的需求&#xff1a; 零成本…

头歌-机器学习 第10次实验 逻辑回归

第1关&#xff1a;逻辑回归核心思想 任务描述 本关任务&#xff1a;根据本节课所学知识完成本关所设置的编程题。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 什么是逻辑回归&#xff1b; sigmoid函数。 什么是逻辑回归 当一看到“回归”这两个字&a…

企业出海--跨境时延测试(拉美篇)

随着全球化不断发展&#xff0c;中国企业也不断向海外拓展业务&#xff0c;开拓市场&#xff0c;增加收入来源&#xff0c;扩大自身品牌影响力。然而出海企业面临不同以往的困难和挑战&#xff0c;在其中不可避免面临的跨境网络时延问题&#xff0c;如何选择区域进行部署企业业…

QT5.14.2解锁Qt自定义标题栏的无限可能,一键拥有与众不同的个性窗口!

在现代化的软件设计中&#xff0c;个性化和美观是应用程序界面不可或缺的元素。而传统的Qt窗口往往风格单一&#xff0c;标题栏固定死板&#xff0c;这严重限制了界面的灵活性和视觉体验。有没有一种方法&#xff0c;可以摆脱这些束缚&#xff0c;为我们的Qt应用注入无限活力?…

Open CASCADE学习|迭代NCollection_Sequence<gp_Pnt>

目录 1、NCollection_Sequence 2、NCollection_Sequence 3、迭代NCollection_Sequence 3.1使用传统for循环 3.2使用C11范围for循环 3.3 使用迭代器 3.4使用STL算法 3.5转换为其他容器类型 NCollection_Sequence是Open CASCADE Technology (OCCT) 中的一个模板类&#x…

石子合并(区间dp)-java

石子合并问题是经典的区间dp问题&#xff0c;我们需要枚举中间端点k的情况从而来推出dp数组的值。 文章目录 前言 一、石子合并问题 二、算法思路 1.问题思路 2.状态递推公式 二、代码如下 代码如下&#xff08;示例&#xff09;&#xff1a; 2.读入数据 3.代码运行结果如下&am…

JS生成二维码.jquery.qrcode.min.js

jquery.qrcode.min.js下载地址 https://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js 1. 生成二维码到img标签 <div style"display:none;" id"qrcodeHide"><img id "qrcode"/>var qrcodeHide jQuery(#qrcodeHide).…

防火墙对于网络攻击都有哪些防御措施?

现如今随着网络技术的快速发展&#xff0c;给人们的生活带来了很多的便利&#xff0c;网络技术也被广泛地应用在各个领域和行业当中&#xff0c;但是在这个过程中也会面临各种网络安全的威胁&#xff0c;给所涉及的企业造成了很大的影响&#xff0c;所以防火墙这一技术&#xf…

yolov9直接调用zed相机实现三维测距(python)

yolov9直接调用zed相机实现三维测距&#xff08;python&#xff09; 1. 相关配置2. 相关代码2.1 相机设置2.2 测距模块2.2 实验结果 相关链接 此项目直接调用zed相机实现三维测距&#xff0c;无需标定&#xff0c;相关内容如下&#xff1a; 1. yolov4直接调用zed相机实现三维测…

LPRNet车牌识别模型训练及CCPD数据集预处理

LPRNet车牌识别模型训练及CCPD数据集预处理 1 LPRNet车牌识别模型训练 1.1 源码:LPRNet_Pytorch-master 源码官网:GitHub - sirius-ai/LPRNet_Pytorch: Pytorch Implementation For LPRNet, A High Performance And Lightweight License Plate Recognition Framework. 链…

Windows搭建Jellyfin影音服务结合内网穿透实现公网访问本地视频文件

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

【Linux】vim 编辑器

Linux 系统自带了 gedit 和 vi 编辑器&#xff0c;gedit 是图形化界面的操作&#xff0c;而 vi 由比较难用&#xff0c;所以建议安装 vim 编辑器&#xff0c;vim 是从 vi 发展出来的一个文本编辑器&#xff0c;相当于增强版的 vi &#xff0c;其代码补完、编译及错误跳转等功能…

【Unity】组件组合使用心得(单行可自动拓展Scroll View)

在这之前&#xff0c;一直是在使用Scroll View进行滑动内容设置&#xff0c;但设置的都是不明不白的&#xff0c;而且有的时候设置好了之后也不知道是为什么&#xff0c;总感觉哪里不对劲&#xff0c;而且好也不知道为什么好&#xff0c;可能是长时间在做管理上的内容&#xff…

【LeetCode热题100】189. 轮转数组(数组)

一.题目要求 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 二.题目难度 中等 三.输入样例 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: …

宝塔的nginx保活(守护)自用

自己用的服务器盒子&#xff0c;刷的海思&#xff0c;宝塔可能有点小问题&#xff0c;因为是朋友给的&#xff0c;剩下的问题就自己解决吧。 整体运行还算稳定&#xff0c;因为我只跑跑nginx/php/docker&#xff08;mysql跑不了&#xff09;&#xff0c;性能勉强够用&#xff…

【操作系统】CentOS7入门级安装

下载镜像 CentOS镜像下载Download (centos.org) 我们选择第一个 X86_64 CentOS Mirrors List 版本描述X86_X64带64位的32位扩展版(一般安装这个)ARM64 (aarch64)嵌入式。适用于微端(树莓派、机械臂、机械中控)IBM Power (ppc64le)专用于IBM POWER服务器 选择一个合适的链接 …

【运维】Ubuntu 配置DNS服务器

背景 异常表现 部分域名无法解析&#xff0c;表现为 ping ***.com 提示 ping: ***.com: No address associated with hostname尝试解决方案 采用 sudo vim /etc/resolv.conf编辑的形式&#xff0c;指定DNS解析服务器 原始内容如下&#xff1a; nameserver 127.0.0.53 opti…