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

C++新经典10--vector以及其使用

vector

vector类型是一个标准库中的类型,代表一个容器、集合或者动态数组这样一种概念。既然是容器,那就可以把若干个对象放到里面。当然,这些对象的类型必须相同。简单来说,可以把一堆int型数字放到vector容器中去,复杂点说,可以把一堆相同类型的类对象放到vector容器中去。

所以,如果换个角度考虑,vector能把其他对象装进来,所以称为容器非常合适。容器这个概念经常被提及,读者要知道和理解这个概念。

要想使用这种类型,需要在.cpp源文件开头包含vector头文件:
在这里插入图片描述
另外,为了方便引用这种类型,也要书写:
在这里插入图片描述
定义一个vector类型对象。显然,一旦定义出来,这个对象就是容器了。例如想在里面保存int型数据(容器里面所要装的元素类型),看如下代码:
在这里插入图片描述
上面的代码定义了一个vector类型的对象,名字叫作vjihe,这个对象里面保存的就是int型数据。为什么是int型数据呢?读者可以看到,vector后面有一对“<>”,“<>”里面是int,表示这个vector类型的对象(容器)里面存放的是int型对象(int型数据/元素)。

这个<int>的写法读者可能第一次见到,会觉得是一种奇怪的写法,在后面章节中会讲到“类模板”的概念,其实vector就是一个类模板,这里的“<>”实际上是类模板的一个实例化过程。但是类模板的实例化过程眼下对于读者来讲,理解起来还比较生涩,后面学习模板的时候再详细阐述,所以这里笔者换一种说法来帮助读者理解类模板。

vector理解成一个残缺的类类型,这意味着使用时光有类名vector还不够,还需要额外给vector类模板提供其要在其中保存什么类型数据的信息,这个信息就是通过<int>来提供(模板名后跟一对“<>”,“<>”内放入类型信息),所以,在使用vector时,一定要在它后面跟一对“<>”并在其中跟一个该vector容器中要保存的数据(元素)类型的信息,这才算一个完整的类型(完整的类类型)。例如,vector不是一个完整类型,而vector<int>却是一个完整的类型。看看如下范例:
在这里插入图片描述
一般来讲,vector容器里面可以装很多种不同类型的数据作为其元素(容器中装的内容简称“元素”)。看看如下范例:
在这里插入图片描述
但是vector不能用来装引用。请记住,引用只是一个别名,不是一个对象。所以,下面的写法会报语法错误:
在这里插入图片描述

定义和初始化vector对象

(1)空vector。
定义如下:

vector<string> mystr;
//创建一个string类型的空vector对象(容器),
//现在mystr里不包含任何元素

后续就可以用相关的一些操作函数往这个空对象里增加数据了。

例如,可以往这个容器的末尾增加一些数据。这里可以使用vector的成员函数push_back往容器末尾增加数据。看看如下范例,注意看它的下标[0],[1],[2],…不断增长,如图13.3所示。

mystr.push_back("abcd");
mystr.push_back("def");

(2)在vector对象元素类型相同的情况下,进行vector对象元素复制(新副本)。

vector<string> mystr2(mystr);	//把mystr元素复制给了mystr2
vector<string>mystr3 = mystr;	//把mystr元素复制给了mystr3

(3)在C++11中,还可以用初始化列表方法给初值,这个时候用“{}”括起来。

vector<string> def = {"aaa","bbb","ccc"};

当然“{}”里面为空也可以,那就相当于没有初始化,是一个空的vector了。

(4)创建指定数量的元素。请注意,有元素数量概念的初始化,用的都是“()”。

如果不给元素初值,那么元素的初值要根据元素类型而定,例如元素类型为int,系统给的初值就是0,元素类型为string,系统给的初值就是"",但也存在有些类型,必须给初值,否则就会报错。
如下范例演示不给元素初值的情况:

vector<int> ijihe2(20);	//20个元素,下标[0]~[19],每一个元素值都为0
vector<string> sjihe2(5);	//15个元素,下标[0]~[4],每一个元素值都为""

(5)多种初始化。“()”一般表示对象中元素数量这种概念,“{}”一般表示元素的内容这种概念,但又不是绝对。看看如下范例:
在这里插入图片描述

vector对象上的操作

其实,在使用vector时,最常见的情况是并不知道vector里会有多少个元素,使用时会根据需要动态地增加和减少。所以一般来讲,使用者是先创建一个空的vector对象,然后通过代码向这个vector里增加或减少元素。这里将要介绍一些vector类型提供的常用方法。vector上很多的操作和string很相似。
(1)判断是否为空empty(),返回布尔值。

   vector<int> ivec;if (ivec.empty())   //条件成立{   cout<<"ivec为空"<<endl;}

(2)push_back:一个非常常用的方法,用于向vector末尾增加一个元素。

    vector<int> ivec;  //先声明成空的vector对象ivec.push_back(1);ivec.push_back(2);for (int i=3;i<=100;i++){ivec.push_back(i);}

在上面的范例中,注意观察,能够发现,值2在值1的后面(最后插入的元素在vector容器的最末尾)。调试结果如下图所示。

(3)size:返回元素个数。
(4)clear:移除所有元素,将容器清空。
(5)v[n]:返回v中的第n个字符(n是一个整型值),位置从0开始计算,位置值n也必须小于.size(),如果下标引用超过这个范围,或者用下标访问一个空的vector,都会产生不可预测的结果(因为编译器可能发现不了这种错误)
在这里插入图片描述
(6)赋值运算符(=)。

    vector<int> ivec;//先声明成空的vector对象ivec.push_back(1);ivec.push_back(2);for (int i=3;i<=100;i++){ivec.push_back(i);}vector<int> ivec2;ivec2.push_back(111);ivec2=ivec;//也得到了100个元素,用ivec中的内容取代了ivec2中原有内容,上行这个111就//被冲掉了ivec2={12,13,14,15};//用{}中的值取代了ivec2原有值cout<<ivec2.size()<<endl;  //4

(7)相等和不等(==和!=)。
两个vector对象相等:元素数量相同,对应位置的元素值也都相同。否则就是不相等。
在这里插入图片描述
(8)范围for的应用:和讲解string时对范围for的应用类似

    vector<int> vecvalue{1,2,3,4,5 };for(auto& vecitem:vecvalue)  //为了修改vecvalue内部值,这里是引用,引用会绑定到元素上,达//到通过引用改变元素值的目的vecitem *= 2;       //扩大一倍for (auto vecitem : vecvalue)cout << vecitem << endl;

针对范围for语句,这里希望引申一步进行讲解。如果在范围for中,增加改变vector容量的代码,则输出就会变得混乱:

    vector<int> vecvalue{1,2,3,4,5 };for (auto vecitem : vecvalue){vecvalue.push_back(888);cout << vecitem << endl;}

范围for,在这里用来遍历vector容器中的元素。这里的vecitem是定义的一个变量,后面的vecvalue是一个序列(容器),for语句中使用auto来确保序列中的每个元素都能够转换成变量vecitem对应的类型,所以一般在范围for语句中习惯使用auto(编译器来指定合适的vecitem类型)。

那为什么上述代码会产生混乱的输出呢?

因为每次执行for循环,都会重新定义vecitem,并且把它的值初始化成vecvalue序列中的下一个值。在刚刚进入这个for循环时,在系统内部会记录序列结束的位置值,但一旦在这个范围for里面改动这个序列的容量(如增加/删除元素),那么这个序列结束的位置值就肯定会发生改变,这个改变会导致for语句的混乱,其输出的值也就乱了。

所以,请记住一个结论,在for语句中,不要改变vector的容量,增加、删除元素都不可以。请读者千万千万不要写出这种错误代码,否则隐患无穷,切记切记!

迭代器精彩演绎、失效分析及弥补、实战

迭代器简介

迭代器是一个经常听到和用到的概念。上一节学习了vector,笔者说过,这是一个容器,里面可以容纳很多对象。那迭代器是什么呢?迭代器是一种遍历容器内元素的数据类型。这种数据类型感觉有点像指针,读者就理解为迭代器是用来指向容器中的某个元素的。

string可以通过“[]”(下标)访问string字符串中的字符,vector可以通过“[]”访问vector中的元素。但实际上,在C++中,很少通过下标来访问它们,一般都是采用迭代器来访问。

除了vector容器外,C++标准库中还有几个其他种类的容器。这些容器都可以使用迭代器来遍历其中的元素内容。string其实是字符串,不属于容器,但string也支持用迭代器遍历。

通过迭代器,可以读取容器中的元素值、修改容器中某个迭代器所代表(所指向)的元素值。此外,迭代器可以像指针一样——通过++、–等运算符从容器中的一个元素移动到另一个元素。

许多容器如上述的vector,在C++标准库中,还有其他容器如list、map等都属于比较常用的容器,C++标准库为每个这些容器都定义了对应的一种迭代器类型,有很多容器不支持“[]”操作,但容器都支持迭代器操作。写C++程序时,笔者也强烈建议读者不要用下标访问容器中的元素,而是用迭代器来访问容器中的元素。

容器的迭代器类型

刚刚讲过,C++标准库为每种容器都定义了对应的迭代器类型。这里就以容器vector为例,演示一下:

    vector<int> iv = {100,200,300};     //定义一个容器vector<int >:: iterator iter;       //定义迭代器,也必须是以vector<int>开头

上面的语句是什么意思呢?后面这条语句定义了一个名为iter的变量(迭代器),这个变量的类型是vector<int>::iterator类型,请注意这种写法“::iterator”。iterator是什么?它是每个容器(如vector)里面都定义了的一个成员(类型名),这个名字是固定的,请牢记。
在理解的时候,就把整个vector<int>::iterator理解成一种类型,这种类型就专门应用于迭代器,当用这个类型定义一个变量的时候,这个变量就是一个迭代器。

迭代器begin/end、反向迭代器rbegin/rend操作

1.迭代器

每一种容器,如vector,都定义了一个叫begin的成员函数和一个叫end的成员函数。这两个成员函数正好用来返回迭代器类型。看看如下范例。
(1)begin返回一个迭代器类型(就理解成返回一个迭代器)。
在这里插入图片描述
(2)end返回一个迭代器类型(就理解成返回一个迭代器)。
在这里插入图片描述
对上面的代码进行跟踪调试,观察begin和end结果可以看到,end()指向了一个乱数字,如图13.5所示。

    vector<int> iv = {100,200,300};     //定义一个容器vector<int >::iterator iter;       //定义迭代器,也必须是以vector<int>开头iter = iv.begin();iter = iv.end();

在这里插入图片描述
(3)如果容器为空,则begin返回的迭代器和end返回的迭代器相同。看看如下范例:

    vector<int> iv2;vector<int>::iterator iterbegin = iv2.begin();vector<int>::iterator iterend = iv2.end();if (iterbegin == iterend)   //条件成立{cout << "容器为空" << endl;}

在这里插入图片描述

所以,end返回的迭代器并不指向容器vector中的任何元素,它起到实际上是一个标志(岗哨)作用,如果迭代器从容器的begin位置开始不断往后游走,也就是不断遍历容器中的元素,那么如果有一个时刻,iter走到了end位置,那就表示已经遍历完了容器中的所有元素。
(4)写一段代码,传统的通过迭代器访问容器中元素的方法如下:

    vector<int>iv={100,200,300};    //定义一个容器//经典传统用法,这里用++、!=等运算符来对迭代器进行操作for (vector<int>::iterator iter = iv.begin();iter != iv.end();iter++){cout << *iter << endl;}

运行起来看结果:100、200、300。

2.反向迭代器

如果想从后面往前遍历一个容器,那么,用反向迭代器就比较方便。反向迭代器使用的是rbegin成员函数和rend成员函数。
(1)rbegin返回一个反向迭代器类型,指向容器的最后一个元素。
(2)rend返回一个反向迭代器类型,指向容器的第一个元素的前面位置。
rbegin和rend成员函数指向的容器位置示意图如图13.7所示。
在这里插入图片描述
看看如下范例:

    vector<int>iv={100,200,300};for (vector<int>::reverse_iterator riter = iv.rbegin(); riter != iv.rend(); riter++){cout<<*riter<<endl;}

运行起来看结果:300、200、100。

迭代器运算符

(1)iter:返回迭代器iter所指向元素的引用。必须要保证该迭代器指向的是有效的容器元素,不能指向end,因为end是末端元素后面的位置,也就是说,end已经指向了一个不存在元素。前面的cout≪iter≪endl;就是使用*iter的演示范例,这里不做进一步演示了。
(2)++iter:和iter++是同样的功能——让迭代器指向容器中的下一个元素。但是已经指向end的迭代器,不能再++,否则运行时报错。
(3)–iter:和iter–是同样的功能——让迭代器指向容器中的前一个元素。了解++自然也就能了解–。看看如下范例:
在这里插入图片描述
(4)iter1==iter2或iter1!=iter2:判断两个迭代器是否相等。如果两个迭代器指向的是同一个元素,就相等,否则就不相等。
(5)结构成员的引用。看看如下范例:
在这里插入图片描述
请注意,一定要确保迭代器指向有效的容器中的元素,否则范例中的这些行为可能会导致意想不到的结果。还有很多其他运算符,例如迭代器之间可以相减表示两个迭代器之间的距离,迭代器加一个数字表示跳过多少个元素,不过这些都不常用,不准备逐一介绍,意义也不大。读者如果以后遇到,有了现在所学的基础,再简单学习一下即可。

const_iterator迭代器

前面学习了iterator这种迭代器类型,实际上每种容器还有另外一种迭代器类型,叫作const_iterator,从名字上能感觉到其含义:有const在,一般都表示常量,也就是说值不能改变的意思。这里的值不能改变表示该迭代器指向的元素的值不能改变,并不表示该迭代器本身不能改变,该迭代器本身是能改变的,也就是说,该迭代器是可以不断地指向容器中的下一个元素的。

所以该迭代器只能从容器中读元素,不能通过该迭代器修改容器中的元素。所以说,从感觉上来讲,const_iterator更像一个常量指针,而iterator迭代器是能读能写的。看看如下范例:

在这里插入图片描述
什么时候用const_iterator呢?如果这个容器对象是一个常量,那么就必须使用const_iterator,否则报错:
在这里插入图片描述
这里再额外看一看cbegin和cend成员函数。这是C++11引入的两个新函数,与begin、end非常类似。但是,不管容器是否是常量容器,cbegin、cend返回的都是常量迭代器const_iterator。看看如下范例:
在这里插入图片描述

迭代器失效

上一节在讲vector容器时谈过范围for循环语句——在遍历容器的时候,如果在for循环中,通过push_back等手段往容器中增加元素,范围for循环输出的容器中元素就会混乱。其实,范围for语句等价于常规的用迭代器对容器进行操作。看如下代码:

    vector<int> vecvalue{1,2,3,4,5 };for (auto vecitem:vecvalue){cout << vecitem <<endl;}

等价于迭代器这种操作方式:
在这里插入图片描述
但如果一旦在for循环中增删容器中的元素,就会导致迭代器失效,整个结果就混乱了。
其实,任何一种能够改变vector对象容量的操作,如push_back,都会使当前的vector对象迭代器失效,所以请读者谨记:在操作迭代器的过程中(使用了迭代器的这种循环体),千万不要改变vector对象的容量,也就是不要增加或者删除vector容器中的元素。看如下代码:
在这里插入图片描述
对于向容器中添加元素和从容器中删除元素操作要小心,因为这些操作可能都会使指向容器元素的迭代器(也包括指针、引用等)失效。这种失效就表示它不能再代表任何容器中的元素,一旦使用这种失效的迭代器,就表示程序的书写犯了严重错误,很多情况下都会导致程序崩溃,就好比使用了没有被初始化的指针一样。

不同的容器实现机理不同(例如有的容器内部数据是连续存储的,插入元素时一旦原有内存不够用,则可能就会导致容器中原有数据全部迁移到一个新内存去,如vector等容器),不同的插入操作、不同的插入位置,会导致迭代器、指针、引用部分或者全部失效,甚至在循环体中的诸如vecvalue.end()代码都会因为插入数据操作导致失效。

另一种情况是删除操作。如果从容器中删除一个元素,那么,当前指向这个被删除元素的迭代器、指针、引用肯定是立即失效,绝不能再引用它们。

此外,不同的容器,针对删除操作,不同的删除位置,也会导致迭代器、指针、引用部分或者全部失效,甚至在循环体中的诸如vecvalue.end()代码都会因为删除数据操作导致失效。

解决方法就是:如果在一个使用了迭代器的循环中插入元素到容器,那只插入一个元素后就应该立刻跳出循环体,不能再继续用这些迭代器操作容器。看看如下范例:
在这里插入图片描述
下面将进行一些灾难程序演示。
(1)灾难程序演示1
下面代码目前一切没有问题:
在这里插入图片描述
接着,往循环中增加代码,注意while循环体中代码的变化:
在这里插入图片描述
有些人可能有更多需求,例如就是想不断地插入多条数据,并且还希望迭代器不失效,那就得查资料研究,如研究针对vector容器,如何写insert这段代码,才能让迭代器不失效,让程序安全地运行。看如下代码,是一种满足连续插入多条数据的解决方案:
在这里插入图片描述

相关文章:

C++新经典10--vector以及其使用

vector vector类型是一个标准库中的类型&#xff0c;代表一个容器、集合或者动态数组这样一种概念。既然是容器&#xff0c;那就可以把若干个对象放到里面。当然&#xff0c;这些对象的类型必须相同。简单来说&#xff0c;可以把一堆int型数字放到vector容器中去&#xff0c;复…...

std : : vector

一.简介 std::vector 的底层实现通常基于动态数组&#xff08;dynamic array&#xff09;&#xff0c;它是一种连续分配的内存块&#xff0c;允许元素的快速随机访问。下面是 std::vector 的一些关键特点和底层实现细节&#xff1a; 连续内存块&#xff1a;std::vector 内部使…...

AJAX学习笔记8 跨域问题及解决方案

AJAX学习笔记7 AJAX实现省市联动_biubiubiu0706的博客-CSDN博客 跨域:指一个域名的网页去请求另外一个域名资源.比如百度页面去请求京东页面资源. 同源与不同源三要素:协议,域名,端口 协议一致,域名一致,端口一致.才算是同源.其他一律不同源 新建项目测试: 1.window.open();…...

webhook--详解(gitee 推送)

一、简介 webhook 是一种基于 HTTP 的回调函数&#xff0c;可在 2 个应用编程接口&#xff08;API&#xff09;之间实现轻量级的事件驱动通信。是一种新型的前后端交互方式&#xff0c;一种对客户端-服务器模式的逆转&#xff0c;在传统方法中&#xff0c;客户端从服务器请求数…...

高速路自动驾驶功能HWP功能定义

一、功能定义 高速路自动驾驶功能HWP是指在一般畅通高速公路或城市快速路上驾驶员可以放开双手双脚&#xff0c;同时注意力可在较长时间内从驾驶环境中转移&#xff0c;做一些诸如看手机、接电话、看风景等活动&#xff0c;该系统最低工作速度为60kph。 如上两种不同环境和速度…...

Leetcode113. 路径总和 II

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 官方题解&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全…...

分布式锁之redis实现

docker安装redis 拉取镜像 docker pull redis:6.2.6 查看镜像 启动容器并挂载目录 需要挂在的data和redis.conf自行创建即可 docker run --restart always -d -v /usr/local/docker/redis/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/docker/redis/data:/dat…...

Idea中如何在一个项目中引入其他子模块?

首先在Settings打开Project Structure&#xff0c;然后找到Modules&#xff0c;点击加号点击import module&#xff0c;将需要引进的module引进来。 然后点击Artifacts 可以看到比如说day22…这个是我现在的项目&#xff0c;day16是我需要引入的。那么就在红色横线上面右键点第…...

UDP协议概述

传输层里比较重要的两个协议&#xff0c;一个是 TCP&#xff0c;一个是 UDP。TCP 是面向连接的&#xff0c;UDP 是面向无连接的。 所谓的建立连接&#xff0c;是为了在客户端和服务端维护连接&#xff0c;而建立一定的数据结构来维护双方交互的状态&#xff0c;用这样的数据结…...

Python-tracemalloc-跟踪内存分配

tracemalloc 模块是一个用于对 python 已申请的内存块进行debug的工具。它能提供以下信息: 定位对象分配内存的位置 按文件、按行统计python的内存块分配情况: 总大小、块的数量以及块平均大小。 对比两个内存快照的差异&#xff0c;以便排查内存泄漏 显示前10项 显示内存…...

02 CSS技巧

02 CSS技巧 clip-path 自定义形状&#xff0c;或者使用自带的属性画圆等circle HTML结构 <body><div class"container"></div> </body>CSS结构 使用*polygon*自定义形状 .container {width: 300px;height: 300px;background-color: re…...

Yarn资源调度器

文章目录 一、Yarn资源调度器1、架构2、Yarn工作机制3、HDFS、YARN、MR关系4、作业提交之HDFS&MapReduce 二、Yarn调度器和调度算法1、先进先出调度器&#xff08;FIFO&#xff09;2、容量调度器&#xff08;Capacity Scheduler&#xff09;3、公平调度器&#xff08;Fair …...

android上架备案公钥和md5获取工具

最近很多公司上架遇到了一个问题&#xff0c;就是要提供app的备案证明&#xff0c;现在android上架都需要备案了&#xff0c;但是我们的证书都是通过工具生成的&#xff0c;哪里知道公钥和md5那些东西呢&#xff1f;无论安卓备案还是ios备案都需要提供公钥和md5。 包括ios的备案…...

SpringBoot系列(12):SpringBoot集成log4j2日志配置

最近项目上有使用到log4j2日志模板配置&#xff0c;本文简单总结一下之前的学习笔记&#xff0c;如有纰漏之处&#xff0c;请批评指正。 1. log4j2日志依赖 使用log4j2日志模板时&#xff0c;需要引入相关依赖&#xff0c;下边的两种依赖方式均可。 1.1 使用sl4j依赖时 <…...

HTML事件列表

鼠标事件 属性描述DOMonclick当用户点击某个对象时调用的事件句柄。2oncontextmenu在用户点击鼠标右键打开上下文菜单时触发ondblclick当用户双击某个对象时调用的事件句柄。2onmousedown鼠标按钮被按下。2onmouseenter当鼠标指针移动到元素上时触发。2onmouseleave当鼠标指针…...

并发-Executor框架笔记

Executor框架 jdk5开始&#xff0c;把工作单元与执行机制分离开来&#xff0c;工作单元包括Runable和Callable&#xff0c;执行机制由Executor框架来提供。 Executor框架简介 Executor框架的两级调度模型 Java线程被一对一映射为本地操作系统线程 java线程启动会创建一个本…...

【C进阶】分析 C/C++程序的内存开辟与柔性数组(内有干货)

前言&#xff1a; 本文是对于动态内存管理知识后续的补充&#xff0c;以及加深对其的理解。对于动态内存管理涉及的大部分知识在这篇文章中 ---- 【C进阶】 动态内存管理_Dream_Chaser&#xff5e;的博客-CSDN博客 本文涉及的知识内容主要在两方面&#xff1a; 简单解析C/C程序…...

深入理解 JVM 之——字节码指令与执行引擎

更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 类文件结构 Write Once&#xff0c;Run Anywhere 对于 C 语言从程序到运行需要经过编译的过程&#xff0c;只有经历了编译后&#xff0c;我们所编写的代码才能够翻译为机器可以直接运行的二进制代码&#x…...

C++:vector

目录 一、关于vector 二、vector的相关函数 三、相关函数的使用 ①构造函数 ②size ③[] ​编辑 ④push_back ⑤迭代器iterator ⑥reserve ⑦resize ⑧find ⑨insert ⑩erase ⑪sort 一、关于vector vector比较像数组 观察可知&#xff0c;vector有两个模板参数…...

Android Automotive编译

系统准备 安装系统 准备一台安装Ubuntu系统的机器&#xff08;windows系统的机器可以通过WSL安装ubuntu系统&#xff09; 安装docker 本文使用docker进行编译&#xff0c;因此提前安装docker。参考网络链接安装docker并设置为不使用sudo进行docker操作。 参考链接&#xff…...

抖音无水印视频下载终极指南:5分钟快速掌握免费批量下载技巧

抖音无水印视频下载终极指南&#xff1a;5分钟快速掌握免费批量下载技巧 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback…...

jQuery WeUI移动端UI组件库架构解析与实现原理深度指南

jQuery WeUI移动端UI组件库架构解析与实现原理深度指南 【免费下载链接】jquery-weui 由于前端业界早已以React/Vue/Angular为主&#xff0c;个人也多年未使用过jQuery&#xff0c;此仓库已不再维护。推荐大家尽快转向 AntD、Element等更先进的UI库&#xff0c;https://ant.des…...

免费公式识别神器:img2latex-mathpix本地部署完全指南

免费公式识别神器&#xff1a;img2latex-mathpix本地部署完全指南 【免费下载链接】img2latex-mathpix Mathpix has changed their billing policy and no longer has free monthly API requests. This repo is now archived and will not receive any updates for the foresee…...

【M1 Mac游戏开发环境】从零到一:VSCode、Git与效率工具的终极配置指南

1. M1 Mac开箱配置&#xff1a;为Unity开发者量身定制 刚拿到M1 Mac的Unity开发者们&#xff0c;你们是否遇到过这样的场景&#xff1a;打开VSCode写C#脚本时智能提示迟迟不出现&#xff0c;Git命令输到一半发现没有自动补全&#xff0c;或是被各种环境配置问题折腾得焦头烂额&…...

告别软件模拟!用GD32F303硬件I2C驱动AT24C02 EEPROM保姆级教程(附完整代码)

从软件模拟到硬件加速&#xff1a;GD32F303硬件I2C驱动AT24C02全流程解析 当你在嵌入式项目中频繁操作EEPROM时&#xff0c;是否遇到过这样的困扰&#xff1a;软件模拟I2C占用大量CPU资源&#xff0c;时序稳定性受中断影响&#xff0c;传输速率始终无法突破瓶颈&#xff1f;这些…...

连开车回家都靠肌肉记忆——芯片工程师到底有多累

下班开车&#xff0c;到家的时候不记得路上发生了什么。这件事很多芯片工程师都经历过。那种精神层面的透支——脑子里塞满了太多东西&#xff0c;意识没有余量去关注开车这件事&#xff0c;只能交给身体的自动驾驶。体力劳动的疲惫&#xff0c;睡一觉就好了。芯片研发的疲惫不…...

开源智能抓取系统Elsa-OpenClaw:从感知到执行的完整技术栈解析

1. 项目概述&#xff1a;当开源大模型遇上“机械爪”最近在AI和机器人交叉领域&#xff0c;一个名为“Elsa-OpenClaw”的项目引起了我的注意。乍一看&#xff0c;这像是一个将大型语言模型&#xff08;LLM&#xff09;与机械臂末端执行器&#xff08;俗称“机械爪”&#xff09…...

9. 找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。方法一&#xff1a;哈希表class Solution(object):def findAnagrams(self, s, p):result{}result["".join(sorted(p))][]for i in ra…...

【LangChain】 入门:从分步调用到链式编程

LangChain 入门&#xff1a;从分步调用到链式编程本文基于一段翻译助手的示例代码&#xff0c;讲解 LangChain 的核心概念、输出解析器的作用&#xff0c;以及普通写法与链式写法的对比。一、LangChain 是什么&#xff1f; 名字拆解缩写含义LangLanguage&#xff08;语言&#…...

3分钟学会Xbox Game Pass存档提取:免费工具实现跨平台游戏进度迁移

3分钟学会Xbox Game Pass存档提取&#xff1a;免费工具实现跨平台游戏进度迁移 【免费下载链接】XGP-save-extractor Python script to extract savefiles out of Xbox Game Pass for PC games 项目地址: https://gitcode.com/gh_mirrors/xg/XGP-save-extractor 作为游戏…...