C++——string类

ops/2024/9/20 3:55:31/ 标签: c++, 开发语言

1.初识string

string属于C++标准库,而不属于STL,STL也属于C++标准库

string是管理字符的顺序表,用来管理字符数组

string是模板,只是库直接给它typedef了,直接实例化

string是动态开辟的字符数组,指向的空间在堆上,可以动态增长

string的接口设计的非常的繁杂

自定义类型实现流插入和流提取要重载,但这里在库里已经实现了

void TestString1()
{string s1;//构造无参的cin >> s1;cout << s1 << endl;
}

2.string的构造函数

2.1无参数构造函数

void TestString1()
{char arr[10];//C语言的问题是,没办法很好地按需去申请空间string s1;//构造无参的cin >> s1;cout << s1 << endl;
}

2.2字符串构造

void TestString1()
{string s2("hello");
}

2.3拷贝构造函数

void TestString1()
{string s1;//构造无参的string s2("hello");string s3(s2);cout << s3 << endl;
}

2.3.1补充

void TestString2()
{string s1("hello");string s2="hello";//为什么支持这种写法?//单参数的构造函数支持隐式类型转换//这里是构造加拷贝构造,然后优化}

2.4substring(3)

void TestString6()
{string s1("hello world");string s2(s1);cout << s2 << endl;string s3(s1, 6, 3);cout << s3 << endl;//worstring s4(s1, 6, 5);cout << s4 << endl;//world}

void TestString6()
{string s5("hello worldxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyy");string s6(s5, 6);
//想把第6个位置及其后面的字符全部取到,怎么做?难道一个个地数吗?
//此时就可以使用缺省参数nposcout << s6 << endl;string s7(s5, 6,s5.size()-6);//使用size也可以cout << s7 << endl;//注意:strlen不可以对自定义类型使用//strlen(s5._str);//这里不可行,_str是私有变量//而且STL有很多版本,你无法得知对象中的私有变量名称}

npos是里面的静态成员变量,给的值是-1,但npos的类型是size_t(unsigned integer:无符号整型)
在底层存储的是补码,-1的补码是全1,类型提升、转换,转换成无符号整型就是整型的最大值:42亿9千万左右
1G是 2^30   4G就是 2^32 byte ,也就是42亿9千万左右
一个string对象不会有4G那么大,所以npos完全够用
32位下new 1G还可以,2G就new不出来了,开不了那么大的连续空间,内存不够

如果len太长,字符串太短,此时也不会越界去访问,有多少取多少,直到字符串结束

2.5from sequence(5)

使用前n个去初始化

void TestString8()
{string s1("hello world",5);cout << s1 << endl;//hellostring s2("hello world", 9);cout << s2 << endl;//hello wor}

2.6fill(6)

使用n个c去初始化

void TestString7()
{string s1(10,'a');cout << s1 << endl;//aaaaaaaaaastring s2(3,'x');cout << s2 << endl;//xxx}

2.7range(7)

void TestString9()
{//使用迭代器区间去初始化string s1("hello world");string s2(s1.begin(), s1.end());cout << s2 << endl;//hello worldstring s3(++s1.begin(), --s1.end());//第一个和最后一个不要cout << s3 << endl;//ello worl
}

2.8赋值运算符重载

void TestString10()
{string s1("hello");cout << s1 << endl;string s2("world");cout << s2 << endl;//一、s1 = s2;cout << s1 << endl;//二、s1 = "hello world";cout << s1 << endl;//三、s1 = 'x';cout << s1 << endl;}

3.string的非成员函数重载(全局函数)

3.1 +

void TestString1()
{string s1;//构造无参的string s2("hello");string ret1 = s1 + s2;//实现字符串的连接cout << ret1 << endl;string ret2 = s1 + "world";cout << ret2 << endl;//C语言实现需要strcat//缺点:1.可读性差//2.需要考虑扩容问题//3.需要找到'\0',如果字符串很长,找'\0'也需要很长的时间string ret3 = s1 + s1;//这里是拷贝而不是往s1后面添加字符串cout << ret3 << endl;
}
void TestString4()
{string s2("hello");string s3 = s2 + 'a';string s4 = s2 + "abcd";//能不使用+就不要使用,因为+是传值返回
}

3.2 relational operators

3.3 swap

3.4operator>>

scanf和cin都有一个特点,如果输入多个值,默认使用空格或者换行来作为间隔分割

void test()
{
//scanf 不能处理内置类型string s1;scanf("%s", s1.c_str());//问题一:返回值是const//问题二:没有开空间
}

3.5 getline

获取一行,遇到空格不结束,遇到换行才结束

还可以自己定义结束符号

#include<iostream>
#include<string>
using namespace std;void test()
{//想以某个指定的字符结束string s1;getline(cin, s1, '!');cout << s1;}

4.string的元素访问

4.1  []

4.2at

at[]的功能是一样的,只是说它不是运算符重载,它就是一个普通的函数

void TestString3()
{	string s1;s1.resize(10, '#');s1[0]++;//使用起来更加形象cout << s1 << endl;s1.at(0)++;//使用起来比较别扭cout << s1 << endl;
}

5.遍历数组

遍历数组的方式有三种:

5.1 []

//遍历数组void TestString2()//访问
{//一、for (size_t i = 0; i < s1.size(); i++){//读cout << s1[i] << " ";}cout << endl;for (size_t i = 0; i < s1.size(); i++){//写s1[i]++;}cout << s1;
}

5.2迭代器

迭代器分为两大类:有无const、正向与反向,组合起来就是4种

5.2.1正向迭代器

//正向迭代器
void TestString3()
{string s1("hello");//二、迭代器
//迭代器是遍历数据结构的一种方式,可以认为它类似一个指针string::iterator it = s1.begin();//一般在类里面定义或是typedef//迭代器定义在类域里面,所以要指定类域//it是对象//begin()是成员函数,一般begin就是返回开始位置的迭代器,返回开始位置的指针//迭代器何时终止?它不等于end就截止了,end是最后一个数据的下一个位置,o是最后一个数据//C++中对字符串是有要求的,为了满足兼容C语言等需求,除了存储有效字符,还要存储'\0'while (it != s1.end()){cout << *it << " ";//只读++it;}cout << endl;//_size是5,与strlen相同,不算'\0','\0'在这里面是一个标识字符,标识结束//所以最后一个有效字符是o,end就指向'\0'}

5.2.2补充

void TestString3()
{string s1("hello");string::iterator it = s1.begin();//while (it != s1.end())while (it < s1.end())//这里可以这样使用,但不建议{cout << *it << " ";++it;}cout << endl;//实际上迭代器才是主流的遍历方式,它是通用的,可以遍历所有容器//同时屏蔽了底层的实现细节,也体现了面向对象的封装list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator lit = lt.begin();while (lit != lt.end())//所以推荐使用!=,因为它是通用的//while (lit < lt.end())//物理空间大概率不连续,是一个个的小块内存,end未必一定比begin大{cout << *lit << " ";lit++;//底层也是cur=cur->next}
}

5.2.3反向迭代器

//反向迭代器
void TestString4()
{string s1("hello");//倒着遍历//string::reverse_iterator rit = s1.rbegin();auto rit = s1.rbegin();//因为rbegin的返回值就是反向迭代器,右边有一个对象,会自动推导左边对象的类型while (rit != s1.rend()){cout << *rit << " ";rit++;//这里++就是反着走的}//这样也可以实现,但是非常别扭string::iterator rit = s1.end();rit--;while (rit != s1.begin()){cout << *rit << " ";//只读--rit;}cout << endl;}

5.2.4有无const

void func(const string& s)
//不推荐传值传参	
// 要进行拷贝,并且这里要去调用拷贝构造,同时拷贝构造要使用深拷贝,否则会出现多次析构的问题
{//string::iterator it = s.begin();//这样写就不支持了string::const_iterator it = s.begin();while (it != s.end()){//const迭代器不支持写//*it = 'a';//读cout << *it << " ";it++;}cout << endl;//string::const_reverse_iterator rit = s.rbegin();auto rit = s.rbegin();while (rit != s.rend()){cout << *rit << " ";rit++;}cout << endl;
}void TestString6()
{string s1("hello");func(s1);}

5.3范围for

void TestString5()
{//三、string s1("hello");//自动判断结束、解引用、++//原理:编译时编译器替换成迭代器//读for (auto ch : s1){cout << ch << " ";}cout << endl;//范围for的底层和第二种遍历方式是完全类似的,把*it赋值给ch//看似代码很短,实际是交给编译器去生成代码了 //范围for不支持倒着遍历for (auto ch : s1){ch++;//s1不会修改}cout <<s1<< endl;//写for (auto& ch : s1)//ch就是*it的别名,这样就可以修改s1{ch++;}cout << s1 << endl;
}

6.Capacity

6.1size

size用来看字符串的有效字符是多少个,不算‘\0’,'\0'是标识字符,标识结束

void TestString11()
{string s1("hello");cout << s1.size() << endl;//不算'\0',打印的是5}

底层在数组上存储的时候要存储‘\0’

为什么要存储‘\0’?明明是个可以动态增长的数组,不要‘\0’也是可以的。

因为要兼容C语言,有些场景下必须要调用C的接口,Linux是用C写的,Linux的接口也是使用C写的,比如有个地方需要传字符串,此时传string是不认识的

void TestString14()
{string filename;cin >> filename;//FILE* fout = fopen(filename, "r");//这里不能编译通过//怎么打开文件?//首先,第一个要传一个常量字符串,C语言规定常量字符串要给'\0'//c_str,即返回C形式的字符串,会返回底层指向字符数组的指针FILE* fout = fopen(filename.c_str(), "r");//C语言对字符串、字符数组的规定是结尾要有'\0'//如果结尾没有'\0',就算提供了c_str,C语言的那些接口也不能很好地兼容,因为不知道字符串的结尾//C语言字符串为什么要加'\0',因为'\0'是标识字符,就知道它结束了,那就可以拿到名字的长度了//这样C++的string就可以和C语言的接口进行完美的配合
}

6.2length

与size作用相同,string产生的比STL要早,C语言最开始给字符串取名字叫strlen,length(长度)明显比size(大小)更为形象,早期的时候字符个数设计的就叫做length,在STL出现后,就开始使用size了,因为size具有通用性,而length不具有,同时其它的数据结构只有size

6.3capacity

计算数组的容量大小,一般情况下不包含'\0'

6.4clear

会清掉数据,但不会释放空间

void TestString12()
{string s1("hello world");cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;s1.clear();cout << endl;//如何判断是否释放了空间?//看capacity,capacity变小就说明释放了cout << s1.size() << endl;cout << s1.capacity() << endl;//二者都是15,证明没有释放空间cout << endl;//STL并未进行严格的规定,但一般来说,clear是不释放空间的//clear一般都是把之前的数据清掉,然后继续插入一些数据//空间比较廉价,没有必要把空间释放掉//最终空间肯定会被释放的,有析构函数s1 += "jxyxtla";cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;}

6.5empty

用来判空

6.6max_size

设计初衷是想知道string最大有多长,最长能到多少

但实际上,1.不同平台下实现不同

2.它非常无用,因为获取的信息也未必准确,比如假设现在内存已经不足了,已经创建了很多对象,开了很多的空间,它就不准确了。这个值是写死的而不是实时变化的。

void TestString13()
{string s1("hello world");cout << s1.max_size() << endl;//内存很足时,可以开21亿(32位)
}

6.7reserve

6.7.1引入

void TestString1()
{//string的扩容//不断插入数据,看capacity的变化,来观察string的扩容string s;size_t old = s.capacity();cout << "初始是" << old << endl;for (size_t i = 0; i < 100; i++){s.push_back('a');if (s.capacity() != old){cout << "扩容为" << s.capacity() << endl;old = s.capacity();}}}

6.7.2应用

// reverse 反转
// reserve 保留
void TestString2()
{//reserve可以提前开空间string s;s.reserve(100);//要100的空间,肯定会去开100,但同时也可能会比100还大size_t old = s.capacity();cout << "初始是" << old << endl;
}

6.7.3补充

void TestString2()
{//那么reserve会不会缩容?s.reserve(10);
//一般是不会缩容,但STL没有严格规定,这只是一般惯例的实现,不同的平台实现都可能不同  
//核心原因还是缩空间这件事不符合我们目前的设计,空间是足够大的cout << "缩容为" << s.capacity() << endl;
}

6.8resize

6.8.1大于15

void TestString3()
{string s("hello world");cout << s << endl;cout << "初始长度为" << s.size() << endl;cout << "初始容量为" << s.capacity() << endl;s.resize(20, 'a');//此时就会扩容cout << s << endl;cout << "改变size后长度为" << s.size() << endl;cout << "改变size后容量为" << s.capacity() << endl;
}

6.8.2大于11小于15

void TestString3()
{string s("hello world");cout << s << endl;cout << "初始长度为" << s.size() << endl;cout << "初始容量为" << s.capacity() << endl;//s.resize(13);s.resize(13,'a');//打印hello worldaa}

6.8.3小于11

void TestString3()
{string s("hello world");cout << s << endl;cout << "初始长度为" << s.size() << endl;cout << "初始容量为" << s.capacity() << endl;s.resize(5);//此时就会删除数据,只保留前5个字符cout << s << endl;cout << "改变size后长度为" << s.size() << endl;cout << "改变size后容量为" << s.capacity() << endl;
}

6.8.4使用场景

void TestString3()
{//使用场景//比如要开一个字符串,要开10个空间,且每个字符都是#string s1;cout << s1 << endl;cout << "初始长度为" << s1.size() << endl;cout << "初始容量为" << s1.capacity() << endl;s1.resize(10, '#');//此时的作用就是开空间+初始化cout << s1 << endl;cout << "使用size后为" << s1.size() << endl;cout << "使用size后为" << s1.capacity() << endl;//核心特点就是要把size改变为所需的值
}

6.9shrink_to_fit

缩容的接口,缩容以后还要插入数据,代价太大,尽量不要使用

7.Modifiers

7.1push_back

void TestString4()
{string s;s.push_back('a');//push_back是插入一个字符s.append("hello world");//插入字符串要使用appendstring s1("hello");s.append(s1);}

7.2append

7.3+=

void TestString4()
{string s;string s1("hello");s += s1;s += "helloc";s += 'x';}

7.4assign

assign有赋值的意思

void TestString5()
{string str;//string str("hello world");//如果已经有一些数据,会把这些数据覆盖掉string base = "The quick brown fox jumps over a lazy dog.";str.assign(base);//把base assign给strstd::cout << str << endl;str.assign(base,5,10);//从第5个位置开始,取10个字符std::cout << str << endl;}

7.5insert

在指定位置前,进行插入数据的操作

void TestString6()
{//之前的数据结构,像顺序表,都是插入一个值//string的特点就是可以插入一个值,也可以插入多个值//因为它的多个值非常好表达,像之前的只能使用数组来表达//而它可以使用字符串来表达,有常量字符串这个概念	string s("hello");cout << s << endl;//头插一个字符只能这样写s.insert(0, 1, 'b');//一、s.insert(s.begin(), 'a');//二、cout << s << endl;//头插需要挪动数据,尽量少使用头插
}

7.6erase

void TestString7()
{string s("hello world");cout << s << endl;s.erase(7);//删除第7个位置及其以后的数据cout << s << endl;}

7.7replace 替换

void TestString8()
{string s("hello world");cout << s << endl;string s1("hello");s.replace(5, 5, s1);cout << s << endl;s.replace(5, 1, "123");cout << s << endl;s.replace(5, 3, "456");//平替覆盖时效率尚可,但凡多一个少一个都要挪动数据cout << s << endl;}

注意:insert、erase和replace尽量不要使用,因为它们都涉及到挪动数据,效率不高
它们的接口设计都是复杂繁多,需要使用时查看文档即可

7.8补充

void TestString8()
{//题目:将空格替换为%10string s2("askjd n nasdnkla lk sknkl nlk");cout << s2 << endl;//以空间换时间的方式string s3;for (auto ch : s2){if (ch != ' '){s3 += ch;}else{s3 += "%10";}}cout << s3 << endl;}

那如果就是要s2改变怎么呢?

7.8.1赋值

void TestString8()
{//一、赋值  开空间,拷贝数据过去s2 = s3;//s2.assign(s3);cout << s2 << endl;}

7.8.2 string的Modifiers::swap

void TestString8()
{//二、string自己提供的swap//本质是交换二者的成员变量  _str、_size、_capacityprintf("s2:%p\n", s2.c_str());printf("s3:%p\n", s3.c_str());s2.swap(s3);cout << s2 << endl;printf("s2:%p\n", s2.c_str());printf("s3:%p\n", s3.c_str());//证明
}

7.8.3全局的swap模板

void TestString8()
{//三、全局的swap可以交换stringswap(s2, s3);cout << s2 << endl;//3次深拷贝,要去调用一次构造、两次赋值,代价太大
}

7.8.4string的非成员函数重载的swap

实际上,上面的代码不会去实例化全局的swap模板
有可以直接去调用的函数,就不用实例化模板了

void TestString8()
{swap(s2, s3);cout << s2 << endl;}

7.9pop_back

8.String operations

8.1 c_str

兼容C语言,有些接口是C的,想把数组传过去就使用c_str

8.2 data

与c_str功能类似

8.3 copy

8.4 substr

8.5 find

void TestString9()
{//假设有一个文件,要求读取这个文件的后缀,怎么做?//文件后缀有个特点,以.为结尾string s1("test.cpp");size_t i = s1.find('.');string s2 = s1.substr(i);//.cppcout << s2 << endl;}

8.5.1应用

void TestString10()
{string s1("https://legacy.cplusplus.com/reference/string/string/substr/");size_t i = s1.find(':');if(i!=string::npos)cout << "协议为:" << s1.substr(0, i) << endl;i+=3;size_t i1 = s1.find('/',i);if (i1 != string::npos)cout << "域名为:" << s1.substr(i, i1-i) << endl;i = i1 + 1;//cout << "资源名为:" << s1.substr(i, s1.size()-1-i) << endl;cout << "资源名为:" << s1.substr(i) << endl;
}

8.6 rfind

void TestString9()
{string s3("test.cpp.tar.zip");//如果文件名是这样的怎么办?size_t i1 = s3.rfind('.');//倒着找string s4 = s3.substr(i1);//.zipcout << s4 << endl;
}

8.7 find_first_of

void TestString11()
{string s1("sajsj ksjald ksljad ljaks");size_t i = s1.find_first_of("abc");//找到第一个出现的该字符串中的任意一个字符while (i!=string::npos){s1[i] = '*';i = s1.find_first_of("abc", i + 1);}cout << s1 << endl;
}

8.7.1补充

void TestString11()
{string s1("sajsj ksjald ksljad ljaks");size_t i = s1.find_first_of("abc");//如果在s1中要遍历m次,在"abc"要遍历n次,则O(n)=m*n//如何减少时间复杂度?int count[256] = { 0 };count[97] = 1;count[98] = 1;count[99] = 1;for (int i = 0; i < s1.size(); i++){if (count[s1[i]] == 1)s1[i] = '*';}cout << s1 << endl;//直接在s1中遍历,这样O(n)就是n了}

8.8 find_last_of

void TestString11()
{string s1("sajsj ksjald ksljad ljaks");size_t i = s1.find_last_of("abc");//同理,但是是倒着找的while (i != string::npos){s1[i] = '*';i = s1.find_last_of("abc", i + 1);}cout << s1 << endl;
}

8.9 find_first_not_of

void TestString11()
{string s1("sajsj ksjald ksljad ljaks");size_t i = s1.find_first_not_of("abc");//找不是"abc"的字符//这里的字符串给的越长,花费的时间就越长,效率就越低while (i != string::npos){s1[i] = '*';i = s1.find_first_not_of("abc", i + 1);}cout << s1 << endl;
}

8.10 find_last_not_of

同理

9.练习

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

//索引就是下标
class Solution {
public:int firstUniqChar(string s) {int Array[26]={0};//计数排序可以很好地解决问题for(auto ch:s){Array[ch-'a']++;//相对映射}for(size_t i=0;i<s.size();i++){if(Array[s[i]-'a']==1){return i;}}return -1;}
};

917. 仅仅反转字母 - 力扣(LeetCode)

//string中的[]对越界的检查是通过断言来检查,[]检查非常严格,一旦越界就会报错
//所以要遵循逻辑:先检查,再访问
class Solution 
{
public:bool IsLetter(char ch){if(ch>='a'&&ch<='z')return true;if(ch>='A'&&ch<='Z')return true;return false;}string reverseOnlyLetters(string s) {int begin=0;int end=s.size()-1;while(begin<end){while(begin<end&&!IsLetter(s[begin]))begin++;while(begin<end&&!IsLetter(s[end]))end--;swap(s[begin],s[end]);begin++;end--;}return s;}
};

415. 字符串相加 - 力扣(LeetCode)

class Solution
{
public:string addStrings(string num1, string num2){int x1 = stoi(num1);int x2 = stoi(num2);return to_string(x1 + x2);}
};
//这样是不可行的,给定的测试值稍大就会超出范围

#include<string>class Solution 
{
public:string addStrings(string num1, string num2) {string s;int end1=num1.size()-1;int end2=num2.size()-1;int next=0;//进位数while(end1>=0||end2>=0){int x1=end1>=0?num1[end1]-'0':0;int x2=end2>=0?num2[end2]-'0':0;int ret=x1+x2+next;next=ret/10;ret=ret%10;s.push_back('0'+ret);//使用尾插效率更高,O(n)=n//使用insert头插也可以是实现,但效率更低,O(n)只有n^2end1--;end2--;}if(next==1){s.push_back('1');}reverse(s.begin(),s.end());//最后逆置就可以了return s;}
};


http://www.ppmy.cn/ops/113240.html

相关文章

Mycat搭建分库分表

分库分表解决的问题 单表数据量过大带来的性能和存储容量的限制的问题&#xff1a; 索引效率下降读写瓶颈存储容量限制事务性能问题分库分表架构 再搭建一对主从复制节点&#xff0c;3307主节点&#xff0c;3309从节点配置数据源 dw1 , dr1,创建集群c1创建逻辑库 CREATE DATAB…

图书管理系统(面向对象的编程练习)

图书管理系统&#xff08;面向对象的编程练习&#xff09; 1.系统演示2.设计框架讲解3.代码的详细讲解3.1 多本书籍的实现3.2 不同操作人员的实现3.3 不同work操作的实现 1.系统演示 下面主要展示系统的删除图书功能和显示图书功能&#xff0c;帮助大家在开始写代码前先了解图…

85-MySQL怎么判断要不要加索引

在MySQL中&#xff0c;决定是否为表中的列添加索引通常基于查询性能的考量。以下是一些常见的情况和策略&#xff1a; 查询频繁且对性能有影响的列&#xff1a;如果某个列经常用于查询条件&#xff0c;且没有创建索引&#xff0c;查询性能可能会下降。 在WHERE、JOIN和ORDER B…

AI应用开发平台Dify本地Ubuntu环境部署结合内网穿透远程管理大模型

文章目录 前言1. Docker部署Dify2. 本地访问Dify3. Ubuntu安装Cpolar4. 配置公网地址5. 远程访问6. 固定Cpolar公网地址7. 固定地址访问 前言 本文主要介绍如何在Linux Ubuntu系统使用Docker快速部署大语言模型应用开发平台Dify,并结合cpolar内网穿透工具实现公网环境远程访问…

系统 IO

"裸奔"层次&#xff1a;不带操作系统的编程 APP(应用程序) -------------------------------- Hardware(硬件) 特点&#xff1a;简单&#xff0c;应用程序直接操作硬件(寄存器) 缺点&#xff1a; 1. 搞应用开发的必须要了解硬件的实现细节&#xff0c;能够看懂原理图…

【数据结构】十大经典排序算法总结与分析

文章目录 前言1. 十大经典排序算法分类2. 相关概念3. 十大经典算法总结4. 补充内容4.1 比较排序和非比较排序的区别4.2 稳定的算法就真的稳定了吗&#xff1f;4.3 稳定的意义4.4 时间复杂度的补充4.5 空间复杂度补充 结语 前言 排序算法是《数据结构与算法》中最基本的算法之一…

QtConcorrent学习、以及与QThread之间的联系

目录 一、QtConcorrent 概述 1、功能 2、特点 3、使用场景 4、QtConcurrent::run 5、应用示例 5、挑战和解决方案 6、QtConcurrent的重要性和价值 二、QFuture 1、主要特点和功能 2、应用示例 三、QtConcorrent与QThread 1、抽象级别和易用性 2. 线程管理和资源利…

C++速通LeetCode简单第6题-环形链表

快慢指针真的很好用&#xff01; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:bool hasCycle(ListNode *head) {//快慢指针ListNode* fast…

2024.9.19

[ABC266F] Well-defined Path Queries on a Namori 题面翻译 题目描述 给定一张有 N N N 个点、 N N N 条边的简单连通无向图和 Q Q Q 次询问&#xff0c;对于每次询问&#xff0c;给定 x i , y i x_i,y_i xi​,yi​&#xff0c;表示两点的编号&#xff0c;请你回答第 x i …

微信小程序开发第三课

1 wxml语法 1.1 模版语法 # 1 在页面 xx.js 的 Page() 方法的 data 对象中进行声明定义 # 2 在xx.wxml 中使用 {{}} 包裹&#xff0c;显示数据 # 3 可以显示如下&#xff0c;不能编写js语句或js方法-变量-算数运算-三元运算-逻辑判断# 4 只是单纯通过赋值&#xff0c;js中…

跨界融合,GIS如何赋能游戏商业——以《黑神话:悟空》为例

在数字化时代&#xff0c;地理信息系统&#xff08;GIS&#xff09;技术正以其独特的空间分析和可视化能力&#xff0c;为游戏产业带来革命性的变革。《黑神话&#xff1a;悟空》作为中国首款3A级别的动作角色扮演游戏&#xff0c;不仅在游戏设计和技术上取得了突破&#xff0c…

【华为杯】第二十一届中国研究生数学建模竞赛

“华为杯”第二十一届中国研究生数学建模竞赛即将开始&#xff0c;梦想科研社给大家整理一些比赛信息&#xff0c;在正式开赛后&#xff0c;我们也会持续分享一些课题的分析以及代码&#xff0c;有需要的可以联系我们获取资料信息哦 一、时间节点 1.加密赛题开始下载时间&…

大数据新视界 --大数据大厂之SaaS模式下的大数据应用:创新与变革

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

计算机三级网络技术总结(二)

RPR使用统计复用的方法传输IP分组IEEE802.16a用于固定结点接入ADSL技术为速率非对称型&#xff0c;上行速率为64kbps~640kbpsRAID是磁盘阵列技术在一定程度上可以提高磁盘存储容量但不能提高容错能力中继器工作在物理层VTP有三种工作模式:VTP Server、VTP Client 和VTP Transpa…

Spring4-IoC2-基于注解管理bean

目录 开启组件扫描 使用注解定义bean Autowired注入 场景一&#xff1a;属性注入 场景二&#xff1a;set注入 场景三&#xff1a;构造方法注入 场景四&#xff1a;形参注入 场景五&#xff1a;只有一个构造函数&#xff0c;无注解 场景六&#xff1a;Autowired和Quali…

通信工程学习:什么是HSS归属用户服务器

HSS&#xff1a;归属用户服务器 HSS&#xff08;归属用户服务器&#xff0c;Home Subscriber Server&#xff09;是IP多媒体子系统&#xff08;IMS&#xff09;中控制层的一个重要组成部分&#xff0c;它扮演着存储和管理用户相关信息的核心角色。以下是关于HSS归属用户服务器的…

计算机毕业设计选题推荐-校园车辆管理系统-Java/Python项目实战(亮点:数据可视化分析、账号锁定)

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

while循环及简单案例

//循环是流程控制中的一个重要分支 //流程控制 条件判断 循环 逻辑处理 //循环的目的和意义 //循环的目的是为了执行一块代码 //循环的意义是为了简化代码。增加代码的复用性 /* //例如输出0-100的数…

Pytorch是如何做显存管理的

参考资料&#xff1a; GPT的回答 自己的实验结果 之前自己在用Pytorch跑模型训练的时候产生了如下一系列问题&#xff1a;1)Pytorch使用的cuda显存什么时候释放 2)什么时候会导致显存堆积 3)如何监控显存的使用。经过查找资料后找到了这些问题的答案&#xff0c;现在记录在此&a…

Node.js快速入门

【图书介绍】《Node.jsMongoDBVue.js全栈开发实战》-CSDN博客 《Node.jsMongoDBVue.js全栈开发实战&#xff08;Web前端技术丛书&#xff09;》(邹琼俊)【摘要 书评 试读】- 京东图书 (jd.com) Node.js运行环境搭建-CSDN博客 本节将介绍如何快速入门Node.js。 1.3.1 Node.…