C++学习——认识什么是STL以及string类的使用

news2024/11/27 16:38:57

目录

一:认识STL

   1.什么是STL

  2.STL当中的各种功能

  3.STL的重要性

  二:认识string类

  1.什么是string

  2.string类相关的使用方法

  Tips1 :constructor

   Tips2:destructor

   Tips3:iterator

  Tips4:capacity

​编辑   Tips5:Element access 

​编辑    Tips6:Modifiers 

     +=操作和+操作字符串拼接

    append字符串拼接

    push_back尾插操作

    assign覆盖原字符串,创建新的字符串

    insert在某个位置上插入指定字符串

    erase删除某段字符串

    replace将某段字符串替换为另外一段字符串

    swap交换两个字符串当中所存储的内容

    pop_back字符串的尾删操作

  Tips7:重要部分的使用演示

   c_str的使用的方式即原因

   find查找成员函数的使用和rfind逆序查找成员函数的使用

一:认识STL

   1.什么是STL

  在日常的程序编写当中,假如我们需要交换两个数据就必须手动书写一个交换函数,之后再进行传参。这样才可以实现两个数据的交换。在很多情况下也是如此,我们通常需要的功能还得自己来写,写完之后才可以使用。相信大多数人都想过:要是我们的各种功能都像已经封装好的库当中的函数那样该有多好,这样我们就可以直接使用了。我们的STL就是这样的一个工具。

  STL是一个封装好的具有各种各样功能的标准库,我们通过调用STL当中的函数可以直接实现我们想要的结果。其中包括我们之前辛辛苦苦所创建好的各种数据结构,这些都在STL当中已经被封装完毕。我们直接使用即可。在STL当中还存在各种各样的算法,比如字符串的逆序等操作。

  2.STL当中的各种功能

  在STL当中一共存在以下的功能:

  其中的迭代器类似于遍历数组等操作。仿函数就是模拟我们正常使用的函数,我们不需要自己定义直接使用即可,算法也就是我们修改数据等操作所需要使用的方法,比如字符串逆序等操作。空间配置器就是自动为我们开辟空间的一个装置,我们只需要像该部分传入一定的参数即可达到自动开辟空间的效果。之后的容器其实就是我们的数据结构当中的各种各样存储和管理数据的方式,比如vector表示顺序表,map表示图,set表示集合等。最上面的配置器我们目前还用不到,到后面我们会进行更加详细的讲解。 

  3.STL的重要性

  由于使用STL可以免去很多不必要的使用上的麻烦,所以当我们在C++代码的编写上面就很提倡使用STL进行各种操作。也正因如此我们在工作面试的时候经常会遇到对于STL标准库知识点的考察,希望大家可以多多积累和学习。

  二:认识string类

  1.什么是string

  在C++语言当中我们还引申加入了很多的额外的功能,比如我们现在需要进行学习的字符串string。大家可能会很好奇为什么会新加入一个字符串呢?我们C语言当中不是已经有过字符串了吗?需要大家注意的是在C语言当中我们的字符串的样子是以下这样的:

char ch[20]="just test for string"

  我们再来详细的观察上面的代码:变量名ch前面的char表示的是ch的类型也就是字符类型,后面的 [ ] 表示的是我们代表一个数组,所以实质上在C语言当中的字符串实质上就是一个字符数组。并不是真正意义上的字符串。并且我们经常会遇到针对于字符串的修改等操作,所以在C++当中我们就专门定义了一个类,用于管理字符串相关的一系列的操作。这就是我们string诞生的原因。

  2.string类相关的使用方法

  首先我们来一点一点的了解以下string当中相关的功能以便于日后我们手动实现他们。

  在我们的string类当中一共存在以上的功能是不是这么看起来我们的string类的功能还是很齐全的呢?我们一个一个来详细的认识并了解。

  Tips1 :constructor

  constructor的意思是建造者,该部分的功能其实就跟命名一样,用于创建我们的字符串的。这一部分的功能类似于我们在类当中所使用的构造函数,为了使我们的使用更加的方便,所以在string类当中我们创建了很多的构造函数,让我们可以以多种形式创建字符串对象。如下图:

  第一个参数为空的代表的就是我们的默认构造,也就是创建一个内容为空的字符串以便于我们以后的使用。如下图:

  下面一个参数当中是一个字符串,所以代表的就是使用一个字符串直接构造我们的字符串,这样就可以省去我们后面的赋值等操作。如下图:

  第三个表示的利用一个字符串当中的下标截取某一段的字符串进行创建显得字符串对象,使用方式如下图:

   需要向大家介绍的是,假如我们使用这一部分进行新的字符串对象构建新的字符串的时候。第二个参数表示的是开始截取的下标的位置,第三个参数是向后面所截取的字符的个数,就像是我们上面代码中所展示的那样:从下标为6的位置开始(也就是 ‘w’ )一共向后截取5个字符,也就是得到(“world”)。

  如果仔细观察的话我们会发现第三个构造函数存在一个默认参数,如果第三个参数被省略的话就会默认取得后面所有的字符进行创建新的字符串。如下图:

  我们会发现就像是我们所介绍的那样取得了后面的所有的字符。

  由于string类当中所需要使用的功能有很多,所以我们在介绍的时候只采用最常用的几种进行详细的介绍,那么最后我们再来看一种构造函数:

std::string s1(5,'*');

  这个构造函数的功能就是使用后面的一个字符进行创建,产生长度为前面参数个的字符串的对象,有时候会产生意想不到的优势。代码如下图:

  运行我们上面的代码,我们会发现产生了五个 ‘ * ’ 长度的字符串。那么经过上面的介绍我们最常用的构造函数就介绍完毕了,下面我们再来向大家介绍下一部分内容。

   Tips2:destructor

  destructor的意思就是析构函数,相信这样就很清楚了吧,这一部分就是string类的析构函数,其实这一部分也没什么好讲解的。通常情况下不需要我们自动调用string类的函数,系统会自动进行相应的处理。

   Tips3:iterator

  iterator的意思迭代器,通常用于修改或者遍历我们的数组。实质上迭代器的原理就类似于我们的指针,在类当中通常会记录下字符串的尾指针放在end当中,同样会记录下字符串的首指针放在begin当中。我们的迭代器就是通过判断首指针和尾指针是否相同进而判断遍历是否结束的。

  想要创建一个可以正常接收迭代器类型的变量就需要在特定的作用空间域下面进行创建,例如begin和end的创建变量的方式为:

  我们需要通过两层作用空间域进行指出目标。即 std::string::iterator 如果已经展开了作用空间域就不需要在重复指定。 

  一般情况下,每一个类当中都会存在一个特定的迭代器,我们只需要在使用的时候调用相应的迭代器即可。使用的方式如下:

  我们创建一个新的迭代器变量it用于接收首指针,之后经过遍历和修改可以修改字符串当中的数据,将原本的 “abcdefg” 每一个字符都加一修改成为 “bcdefgh”。迭代器的优点就在于增加了string类的封装性,是我们不需要自己访问字符串就可以使用并遍历和修改字符串。

  同样的我们要是想要反向的修改并访问字符串也是可以的,这个时候就需要使用到我们的rbegin和rend了。和begin和end的使用方法似乎完全相同,但是唯一不同的就是我们创建接收变量it的方式,对于rbegin和rend因为是反向输出并修改字符串所以我们就需要调用反向的迭代器进行操作。也就是通过 std::string::reverse_iterator 进行创建变量。代码示例如下:

  我们会发现,创建好反向迭代器之后我们其他所有的使用和操作和普通的迭代器都是完全相同的。那么到此为止我们的迭代器相关的内容也就讲解完毕了。

  Tips4:capacity

  由于这一部分大多数都是针对于字符串进行一些简单的判断的操作所以我们直接可以从示例当中进行学习string类当中的相关内容的使用。示例代码如下:

#include<iostream>
#include<string>
int main()
{
	//使用string类创建一个字符串对象,并验证capacity当中的各种操作
	std::string s1("hello world");
	std::cout << "缩小之前的字符串:" << s1 << std::endl << std::endl;

	//返回字符串所占字节的大小
	std::cout <<"最初的size:"<< s1.size() << std::endl << std::endl;

	//返回字符串的长度
	std::cout <<"字符串的长度:"<< s1.length() << std::endl << std::endl;

	//返回字符串所能存储的最大的字符长度
	std::cout <<"最大字符串的长度:"<< s1.max_size() << std::endl << std::endl;

	//返回字符当前字符串的容量
	std::cout <<"字符串的容量:"<< s1.capacity() << std::endl << std::endl;
	
	//对于字符串的长度进行修改,小于目标值就扩容,大于目标值就缩小
	s1.resize(20);
	std::cout <<"调用resize之后修改完毕的size(扩大):"<< s1.size() << std::endl << std::endl;
	s1.resize(5);
	std::cout << "缩小容量之后的字符串:" << s1 << std::endl;
	std::cout << "调用resize之后修改完毕的size(缩小):" << s1.size() << std::endl << std::endl;

	//对字符串的容量进行修改
	std::cout << "修改之前的字符串的容量:" << s1.capacity() << std::endl;
	s1.reserve(55);
	//存在内存对齐的现象,所以可能会比原有的空间大
	std::cout << "修改之后的字符串的容量:" << s1.capacity() << std::endl<<std::endl;
	
	//判断一个字符串是否为空
	std::cout << "判断一个字符串是否为空:" << s1.empty() << std::endl << std::endl;

	//清空一个字符串
	s1.clear();
	std::cout <<"清空之后的字符串:" <<s1 << std::endl;
	std::cout << "清空之后再次进行判空操作:" << s1.empty() << std::endl << std::endl;

	//自动调整size和capacity的大小
	std::cout << "调整之前的字符串的大小:" << s1.size() << std::endl;
	std::cout << "调正之前的字符串的容量:" << s1.capacity() << std::endl;
	s1.shrink_to_fit();
	std::cout << "调整之后的字符串的大小:" << s1.size() << std::endl;
	std::cout << "调正之后的字符串的容量:" << s1.capacity() << std::endl;
	return 0;
}

  我们string类的创建其实类似于我们之前写过的顺序表,为了避免不必要的空间的浪费所以我们会创建一个capacity进行作为创建出的空间是否已满的标志。

  在这一部分当中,size表示字符串所占空间的大小,capacity表示已经为字符串所开辟好的空间,length表示字符串的长度,max_size表示一个字符串所能占据的最大的空间,clear可以清空一个字符串,empty可以对一个字符串进行判空操作,如果字符串为空就返回1,不为空就返回0。这些只需要了解并会使用即可,并不难。

  在这一部分需要着重进行介绍的是:reserve功能和resize功能。

  reseve可以修改一个字符串的容量。也就是针对于空间的申请进行修改,(并不会改变字符串的大小)需要向其中传递一个参数,即新调整之后容量的大小。可能产生两种情况:修改的空间大于原本的容量,修改的空间小于原本的容量。

  如果需要进行修改的空间大于原本的容量,那么我们就会重新进行内存申请,并修改容量。修改之后的空间可能等于我们修改的空间也可能大于我们修改的空间,因为可能存在内存对其的现象。

  如果需要进行修改的空间小于原本的容量,那么之后的操作有可能不被响应,或者交给我们的编译器进行处理。依旧处于一种不可控的状态,所以我们使用reverse调整容量的时候最好向大进行调整,需要避免向小进行调整。

  resize功能可以调整一个字符串的长度,是真正意义上作用于我们的字符串的。同样分为两种情况一种是将字符串的长度缩小,一种是将字符串的长度扩大。 对于resize同样需要我们传入一些参数如下图所示:

  我们可以直接传入一个数字,表示修改空间的大小,还可以传入一个数字和一个字符用于补充该字符到完整的字符串大小。

  当 n 的大小小于原本的字符串长度的时候就会自动删去一部分,删去之后的字符串的长度为n。

  当 n 的大小大于原本的字符串长度的时候看起来没有任何改变,但是由于字符串变长了,会间接影响到capacity的大小,形成扩容的效果。如果不跟后面的字符的话会默认补充 '\0' 。运行效果如下:

   Tips5:Element access 

    这一部分的功能就是对字符串进行指定的修改。就像是平时我们使用的指针类型的数组。我们可以通过解引用或者 [ ] 进行指定位置元素的读取或者修改。

  就像我们之前说到过的,我们一般的操作符只可以作用于内置类型的数据不能作用于自定义类型的数据。所以 [ ] 不能直接作用于string类。要想修改特定位置的值我们就需要重载 [ ] 。我们可以尝试一下:

  我们可以发现字符串当中下标为1的字符已经被修改成为了 * 。同样的,由于特殊的位置我们还特意设置了首元素的修改和尾元素的修改:

   通过调用front和back函数我们可以发现,字符串当中的首元素和尾元素得到了修改。

  在string类当中也有很多功能发生了重复,比如说at。我们实际的作用也是遍历字符串以及修改字符串所产生的,我们只需要进行简单的了解即可:

    Tips6:Modifiers 

  这一部分的作用是修改,也是我们字符串处理当中最常使用的功能。比如像是字符串拼接,字符串数据的增加,尾插等一系列的操作。我们依次来认识一下:

     +=操作和+操作字符串拼接

  首先是将两个字符串拼接的操作符,由于自定义类型不能被相加或者相减所以这一部分照常使用到了我们的运算符重载。通过运算符重载之后就可以将自定义类型进行相加或者相减操作了。示例代码如下:

  使用+拼接的字符串并不会对原字符串产生修改,所以我们需要创建一个新的空字符串进行接收拼接好的新字符串。而使用+=拼接好的字符串会对原字符串造成修改,所以我们只需要直接打印即可。

    append字符串拼接

  之后我们要介绍的是作用很相似的append函数。append函数的作用就是在字符串的后面拼接好另一个字符串。使用append拼接的内容会自动加入到字符串的末尾,不会对原字符串当中的内容造成覆盖。和我们的构造函数很像的是使用append函数拥有很多字符串拼接的形式。

   其中包括使用一个新的string对象进行拼接,直接使用一个字符串进行拼接,使用某个字符串的一部分进行拼接,使用一个字符进行拼接等。由于在构造函数当中我们已经介绍过一遍了,所以我们在这一部分就不过多缀叙了。直接通过代码进行测试:

   同样的使用部分拼接的时候使用的方式和构造函数当中的相同,参数可以省略, 但是作用是完全不同的,参数不省略的话就表示从第n个位置开始截取m个字符。如果省略的话就变成了默认从首元素开始截取,截取m个字符了。如上图所示。

    push_back尾插操作

    使用push_back可以实现字符串的尾插操作。参数为一个字符,作用就是将字符插入到字符串的末尾。代码如下:

  操作如上图所示。 

    assign覆盖原字符串,创建新的字符串

  我们在上面说到过:既然有直接增加不覆盖的字符串操作形式,那么就一定会有覆盖字符串的操作性是。assign的作用就是将原本字符串当中的内容覆盖掉,然后将我们新的字符串填入该字符串当中。其使用方式和append操作完全相同,只不过产生的效果不同。代码如下:

  使用的方式和我们的append完全相同,只不过执行的效果不再是添加而是覆盖原对象而已。 

    insert在某个位置上插入指定字符串

  既然有了头插和尾插的操作肯定会有在任意位置插入字符串的功能。我们的insert函数就是用来实现这一部分功能的。insert函数主要需要两个参数,一个是我们想要插入位置的下标,第二个参数就是我们想要插入的字符串。甚至我们还可以让我们的插入函数更加灵活,我们还可以插入指定字符串的一部分,传参的方式和我们之前使用的方式一样。代码示例如下:

    erase删除某段字符串

  erase的功能是删除字符串当中的指定的部分,通常情况下有两个参数,第一个是一个下标位置,第二个是要删除的元素的个数。这两个都有一个缺省值,第一个参数的缺省值是0,第二个参数是最大值。这也就是说,当我们不向函数传任何参数的时候,函数就会自动删除字符串的所有的内容。测试如下:

    replace将某段字符串替换为另外一段字符串

  replace的作用就是使用一个字符串替代原字符串当中部分内容,这个函数拥有很多的参数,使用的方法也多种多样,最多可以拥有五个参数。分别是(原字符串开始替换的下标,原字符串替换的长度,需要进行替换的字符串,需要替换字符串开始替换的位置,需要替换字符串的长度)。其中,最后两个针对于需要替换字符串的开始位置和替换长度可以省略,如果省略的话就代表替换使用全部字符串。测试代码如下:

    swap交换两个字符串当中所存储的内容

  这一部分其实可以被replace所替代,因为我们只需要指定好参数的话就可以实现指定部分的替换了。测试代码如下:

  实际上就是交换两个字符串当中所存储的内容,只要会使用即可。 

    pop_back字符串的尾删操作

  这个函数就是将我们字符串最后一个字符进行删除,可以简化我们代码的编写,因为针对于一个未知长度的字符串,要想删除最后一个字符需要先求出他的字符串的长度,这样会降低我们代码运行的效率。

  Tips7:重要部分的使用演示

  在这一部分我们将最后最常使用的几个部分一起向大家演示其使用的方法.

   c_str的使用的方式即原因

  c_str的作用就是将字符串对象当中存储的内容转换成为一个可以被编译器所接受的C语言形式的字符。也许string类的存储形式之前或许对大家来说很神秘,其实他就是一个字符串,一个由指针所指向的字符串,我们可以通过c_str得到这个指针,进而打印出相关的对象。测试代码如下:

  实质上这也是我们自定义的类对象可以被cout输出的原因,据我们所知cout无法输出自定义的对象。但是可以输出内置类型的对象,因此我们只需要重定向一下cout输出,将输出的对象转化为字符串的输出打印即可,这个时候也会需要用到c_str函数的接口。

   find查找成员函数的使用和rfind逆序查找成员函数的使用

  这是最后较为重要的一部分内容了,在一个字符串对象当中我们想要查找一个对象的下标位置,我们就可以手动调用find成员函数进行查找。如果找到的话就会返回第一次匹配上的下标的位置。如果没有找到就会返回一个极大值。代码运行的效果如下:

  但是我们可以发现一个弊端:那就是假如我们的字符串当中有好几个相同的内容呢?我们想要查找到的是中间的一部分,或者说是最后的那一部分呢?

   想要查找中间的部分的话我们就需要手动增加参数了,这个成员函数最多可以有三个参数,分别表示所要匹配的字符串,想要开始匹配的位置,以及所要匹配字符串的长度。如果只有一个数字参数的话就会默认为所要开始匹配的字符串的下标,这样我们就可以查找到中间匹配的字符串啦。

  对于最后部分的匹配的字符串,我们可以调用rfind成员函数进行直接从后向前的查找。示例代码如下:

  那么此上就是我们本次博客的全部内容了,感谢您的观看。 

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

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

相关文章

数学建模学习(9):模拟退火算法

模拟退火算法(Simulated Annealing, SA)的思想借 鉴于固体的退火原理&#xff0c;当固体的温度很高的时候&#xff0c;内能比 较大&#xff0c;固体的内部粒子处于快速无序运动&#xff0c;当温度慢慢降 低的过程中&#xff0c;固体的内能减小&#xff0c;粒子的慢慢趋于有序&a…

SQL 相关子查询 和 不相关子查询、Exists 、Not Exists

不相关子查询 子查询的查询条件不依赖于父查询&#xff0c;称不相关子查询。子查询可以单独运行的 select stu_id,sex,age from student t where sex(select sexfrom studentwhere stu_id10023 )相关子查询 关联子查询 子查询的查询条件依赖于父查询&#xff0c;称为 相关子…

【Hystrix技术指南】(6)请求合并机制原理分析

[每日一句] 也许你度过了很糟糕的一天&#xff0c;但这并不代表你会因此度过糟糕的一生。 [背景介绍] 分布式系统的规模和复杂度不断增加&#xff0c;随着而来的是对分布式系统可用性的要求越来越高。在各种高可用设计模式中&#xff0c;【熔断、隔离、降级、限流】是经常被使…

跨境商城系统源码的优势,助力企业海外扩张

跨境电商发展背景与趋势 随着全球化的推进和互联网技术的快速发展&#xff0c;跨境电商已成为企业海外拓展的重要途径。然而&#xff0c;跨境电商面临着诸多挑战&#xff0c;如复杂的海外市场、文化差异、海关监管等。为了解决这些问题&#xff0c;企业可以借助跨境商城系统源码…

连接SAP rfc一直报错如何解决?

问题如下&#xff1a; 代码&#xff1a; static String ABAP_AS_POOLED "ABAP_AS_WITH_POOL";private static Logger log;static {Properties connectProperties new Properties();connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, "IP&q…

vue table动态合并, 自定义合并,参照合并,组合合并

<template><div><el-table:data"tableData":span-method"objectSpanMethod"border:header-cell-style"{ textAlign: center }"><el-table-column prop"area" label"区域" align"center">…

分班问题难?分班查询系统为你解决分班难题

老师们在教学工作中&#xff0c;特别是每个新学年开始&#xff0c;都会面临一个重要的任务——分班。除了分班名单的确定&#xff0c;分班查询也同样困扰老师们&#xff01;在分班过程中面临的难题&#xff0c;最关键的一点是在完成分班名单确定后&#xff0c;分班查询的通知显…

Win7之MS12-020死亡蓝屏

一&#xff0c;何为死亡蓝屏 1&#xff0c;简介 死亡蓝屏利用RDP协议&#xff0c;基于3389远程桌面端口对目标主机进行攻击&#xff0c;使目标机系统瘫痪导致蓝屏&#xff0c;严重影响着计算机的正常使用。 2&#xff0c;条件 1>目标操作系统未开启防火墙和杀毒软件等 2&g…

STM32 LoRa源码解读

目录结构&#xff1a; SX1278 |-- include | |-- fifo.h | |-- lora.h | |-- platform.h | |-- radio.h | |-- spi.h | |-- sx1276.h | |-- sx1276Fsk.h | |-- sx1276FskMisc.h | |-- sx1276Hal.h | |-- sx1276LoRa.h | -- sx1276LoRaMisc.h – src |-- fifo.c |-- lora.c |-- …

Neo4j笔记-数据迁移(导出/导入)

这里先说明以下几点&#xff1a; Neo4j在4.0下版本默认的库名是&#xff1a;graph.db Neo4j在4.0上版本默认的库名是&#xff1a;neo4j.db 不管是Neo4j&#xff0c;还是Neo4j Desktop&#xff0c;都会在bin目录下有neo4j、neo4j-admin软件。在conf目录下&#xff0c;有neo4j.…

mfc140u.dll文件下载安装的方法,修复缺失的mfc140u.dll

关于mfc140u.dll缺失的情况&#xff0c;其实可以说是非常的常见&#xff0c;这个错误可能会导致某些程序无法正常的工作或者是启动&#xff0c;所以我就要想办法去解决它&#xff0c;而解决它的方法就是下载一个新的mfc140u.dll文件&#xff0c;今天我们就来聊聊mfc140u.dll文件…

Java中有哪些可以用于日期和时间的API?

从Java 8开始&#xff0c;java.time包提供了新的日期和时间API&#xff0c;新增的API严格区分了时刻、本地日期、本地时间&#xff0c;并且&#xff0c;对日期和时间进行运算更加方便。主要涉及的类型有以下几类&#xff1a; LocalDate&#xff1a;不包含具体时间的日期。 Lo…

gRPC中interceptor拦截器的总结和实践

一、使用场景 gRPC中的interceptor拦截器分为客户端拦截器和服务端拦截器&#xff0c;分别是在客户端和服务端的请求被发送出去之前进行处理的逻辑。常见的使用场景有&#xff1a;&#xff08;1&#xff09;请求日志记录及监控&#xff1b;&#xff08;2&#xff09;添加请求头…

C++初阶语法——引用,从此和指针说byebye

前言&#xff1a;相信学过C语言的同学肯定被指针深深折磨过&#xff0c;从一级指针到二级指针&#xff0c;数组指针&#xff0c;函数指针等等&#xff0c;可谓是谈针色变。而在C中&#xff0c;使用引用代替了指针的使用&#xff0c;大大降低了我们学习的难度。 引用 一.什么是…

阿里云二级域名配置

阿里云二级域名配置 首先需要进入阿里云控制台的域名管理 1.选择域名点击解析 2.添加记录 3.选择A类型 4.主机记录设置【可以aa.bb或者aa.bb.cc】 到时候会变成&#xff1a;aa.bb.***.com 5.解析请求来源设置为默认 6.记录值 设置为要解析的服务器的ip地址 7.TTL 默认即…

知网行政部门主管_《天津教育》投稿指南

知网行政部门主管_《天津教育》投稿指南 一、《天津教育》期刊简介&#xff1a; 主管单位&#xff1a;天津市教育委员会 主办单位&#xff1a;天津教育报刊社 国际标准刊号ISSN:0493-2099 国内统一刊号CN:12-1044/G4 邮发代号6-9 出版周期&#xff1a;旬刊 出版地&…

Linux usb设备固定端口号

Linux usb设备固定端口号 一:/sys/bus/usb/devices/二:设备信息三:固定usb设备名方法 一:/sys/bus/usb/devices/ 信息显示如下 1-0:1.0 1&#xff1a;表示 1 号总线&#xff0c;或者说 1 号 Root Hub0&#xff1a;表示端口号1&#xff1a;表示配置号0&#xff1a;表示接口号命…

【FeatureBooster】Boosting Feature Descriptors with a Lightweight Neural Network

这篇论文介绍了一种轻量级网络&#xff0c;用于改进同一图像中关键点的特征描述符。该网络以原始描述符和关键点的几何属性作为输入&#xff0c;使用基于多层感知器&#xff08;MLP&#xff09;的自我增强阶段和基于Transformer的交叉增强阶段来增强描述符。增强后的描述符可以…

搭建Repo服务器

1 安装repo 参考&#xff1a;清华大学开源软件镜像站:Git Repo 镜像使用帮助 2 创建manifest仓库 2.1 创建仓库 git init --bare manifest.git2.2 创建default.xml文件 default.xml文件内容&#xff1a; <?xml version"1.0" encoding"UTF-8" ?…

java之junit Test

JUnit测试简介 1.什么是单元测试 单元测试是针对最小的功能单元编写测试代码Java程序最小的功能单元是方法单元测试就是针对单个Java方法的测试 2.测试驱动开发 3.单元测试的好处 确保单个方法运行正常如果修改了方法代码&#xff0c;只需确保其对应的单元测试通过测试代码…