list的总结

目录

1.什么是list

1.1list 的优势和劣势

优势:

劣势:

2.构造函数 

2.1  default (1)

2.2  fill (2)

2.3  range (3)

2.4  copy (4)

3.list iterator的使用

3.1. begin()

3.2. end()

3.3迭代器遍历

4. list容量函数

4.1. empty()

4.2. size()

4.3. max_size()

4.4. front()

4.5. back()

5.list增删查改函数 

5.1 push_front

5.2 pop_front 

5.3  push_back

5.4 pop_back

 5.5 insert

5.6. erase

5.7  swap 

5.8 clear 

 6.list操作函数

6.1. splice

6.2. remove

6.3. unique

6.4. reverse

 7.list的迭代器失效


 追随光靠近光成为光

1.什么是list

在C++标准库中,list 是一个双向链表容器,用于存储一系列元素。与 vector 和 deque 等容器不同,list 使用链表的数据结构来组织元素,因此在某些操作上具有独特的优势和性能特点。以下是关于 list 的详细介绍

1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。
3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。
4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率 更好。
5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这 可能是一个重要的因素)

在使用list 时,需要权衡其优势和劣势,根据实际场景来选择合适的容器。当需要频繁插入和删除元素,且不需要随机访问时,list 可能是一个很好的选择。但需要注意的是,由于链表的特性,list 并不适用于需要快速随机访问元素的场景,因为访问某个位置的元素需要遍历链表

1.1list 的优势和劣势

优势:

插入和删除效率高: 由于 std::list 是双向链表,插入和删除操作在常数时间内完成,不需要涉及内存的重新分配和元素的复制。这使得 std::list 在大量插入和删除操作时非常高效。
迭代器的稳定性: std::list 的插入和删除操作不会使迭代器失效,除非删除的正是迭代器所指向的元素。这使得在遍历过程中进行插入和删除操作更加方便和安全。
空间占用相对稳定: std::list 的空间占用相对稳定,插入和删除操作不会影响其他元素的空间占用。

劣势:

不支持随机访问: 由于链表的结构,list 不支持像数组一样的随机访问。访问某个位置的元素需要从链表的开头或结尾开始遍历。
额外的指针开销:list 中的每个元素都需要存储指向前后元素的指针,这使得空间占用相对其他容器更高。
缓存效率低: 由于链表中元素在内存中的存储位置不连续,导致在访问链表元素时,缓存命中率较低,可能影响性能。
迭代器的使用限制:list 的迭代器不支持与普通指针类似的算术操作(如 + 和 -),因此无法像 vector 那样灵活地进行迭代器操作

2.构造函数 

2.1  default (1)

这个构造函数用于创建一个空的 std::list 容器。它可以接受一个可选的分配器参数,用于指定内存分配策略。

list<int> v; // 创建一个空的 list 容器

2.2  fill (2)

这个构造函数用于创建一个包含 n 个元素的list 容器,并将这些元素初始化为 val。你可以通过传递不同的 val 值来创建一个包含相同值的容器。同样,也可以传递一个可选的分配器参数。

list<int> v(10, 20); // 创建一个包含 10个元素,每个元素都是 20 的list 容器

2.3  range (3)

这个构造函数使用迭代器范围 [first, last) 中的元素创建一个list 容器。这使你可以通过一个迭代器范围来初始化容器。同样,它也接受一个可选的分配器参数。

vector<int> v = {1, 2, 3, 4, 5};
list<int> my(v.begin(), v.end()); // 从迭代器范围内的元素创建list 容器

2.4  copy (4)

这个构造函数用于创建一个与已存在的 list 容器 x 相同的副本。它会将 x中的所有元素拷贝到新的容器中。这是一个拷贝构造函数。

list<int> v = {1, 2, 3, 4, 5};
list<int> my(v); // 创建一个原容器的副本

3.list iterator的使用

3.1. begin()

iterator begin() noexcept;
这个版本的 begin() 返回一个迭代器,可以用于修改容器内的元素。noexcept 表示这个函数不会抛出异常。

list<int> m = {1, 2, 3, 4, 5};
list<int>::iterator it = m.begin(); // 获取可修改元素的迭代器
*it = 10; // 修改第一个元素的值为 10

3.2. end()

iterator end() noexcept;
这个版本的 end() 返回一个迭代器,可以用于修改容器内的元素。noexcept 表示这个函数不会抛出异常。这个迭代器指向的位置实际上是容器的末尾位置之后一个虚拟的位置,所以它并不指向容器内的任何元素。

list<int> m = {1, 2, 3, 4, 5};
list<int>::iterator it = m.end(); // 获取可修改元素的迭代器
--it; // 将迭代器前移一个位置,指向最后一个元素
*it = 20; // 修改最后一个元素的值为 20

3.3迭代器遍历

(list不支持[  ],  只能用迭代器遍历(范围for也可以底层是迭代器))

#include<iostream>
#include<list>
using namespace std;


void mylist()
{
	list<int> m;

	m.push_back(1);
	m.push_back(2);
	m.push_back(3);
 
     //迭代器
	list<int>::iterator it = m.begin();
	while (it != m.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

    //范围for
	for (auto e : m)
	{
		cout << e << " ";
	}
	cout << endl;

}


int main()
{
	mylist();
	return 0;
}

4. list容量函数

4.1. empty()


empty() 是 list 容器的一个成员函数,用于判断容器是否为空。它返回一个布尔值,表示容器是否不包含任何元素。函数声明如下:

bool empty() const noexcept;

返回值:如果容器为空,则返回 true,否则返回 false。

例子 

#include<iostream>
#include<list>
using namespace std;

int main() {
    list<int> m;

    if (m.empty()) {
        cout << "The list is empty." << endl;
    }
    else {
        cout << "The list is not empty." << endl;
    }

    m.push_back(10);

    if (m.empty()) {
       cout << "The list is empty." << endl;
    }
    else {
        cout << "The list is not empty." << endl;
    }

    return 0;
}

4.2. size()

size() 是 list 容器的一个成员函数,用于返回容器中元素的数量。它返回一个无符号整数类型,表示容器中的元素数量。函数声明如下:

size_type size() const noexcept;

返回值:返回容器中元素的数量,即大小。

#include<iostream>
#include<list>
using namespace std;

int main() {
   list<int> m;

    m.push_back(1);
    m.push_back(2);
    m.push_back(3);
    m.push_back(4);
    m.push_back(5);


    cout << "Size of the list: " << m.size() << endl;

    return 0;
}

4.3. max_size()


max_size() 是 list 容器的一个成员函数,用于返回容器可能容纳的最大元素数量,通常受到系统内存限制的影响。它返回一个无符号整数类型,表示容器的最大大小。函数签名如下:

size_type max_size() const noexcept;

返回值:返回容器可能容纳的最大元素数量。

#include<iostream>
#include<list>
using namespace std;

int main() {
   list<int> m;

    cout << "Size of the list: " << m.max_size() << endl;

    return 0;
}

 

4.4. front()

front() 是 list 容器的成员函数,用于返回容器中第一个元素的引用。这个函数有两个版本,一个用于可修改容器的对象,另一个用于只读(const)容器的对象。函数的签名如下:

reference front();

reference:返回一个对容器中第一个元素的非常引用。

加了const是只读的不能被修改

#include<iostream>
#include<list>
using namespace std;

int main() 
{
    list<int> m = {9,2,3,4,5,6};

   int& firstElement = m.front();

    cout << "First element: " << m.front() << endl;

    return 0;
}

 

4.5. back()


back() 是 list 容器的成员函数,用于返回容器中最后一个元素的引用。这个函数有两个版本,一个用于可修改容器的对象,另一个用于只读(const)容器的对象。函数的签名如下:

reference back();
reference:返回一个对容器中最后一个元素的非常引用。

加了const是只读的不能被修改

#include<iostream>
#include<list>
using namespace std;

int main() 
{
    list<int> m = {9,2,3,4,5,6};

   int& firstElement = m.back();

    cout << "Last element: " << m.back() << endl;

    return 0;
}

 

5.list增删查改函数 

函数说明接口说明
push_front
在list首元素前插入值为val的元素
pop_front
删除list中第一个元素
push_back
在list尾部插入值为val的元素
pop_back
删除list中最后一个元素
insert
在list position 位置中插入值为val的元素
erase
删除list position位置的元素
swap
交换两个list中的元素
clear
清空list中的有效元素

5.1 push_front

push_front 是 list 容器的成员函数,用于在容器的开头插入一个新元素。

这个函数有两个版本:

void push_front (const value_type& val);:接受一个常量引用参数,会创建一个新元素并将参数的值拷贝到新元素中。

void push_front (value_type&& val);:接受一个右值引用参数,用于移动构造一个新元素。这样可以避免额外的拷贝操作,提高了效率。

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m;

    int value = 10;

    m.push_front(value); // Copy insert

    cout << "List contents:" << endl;
    for (const auto& num : m) {
        cout << num << " ";
    }
    cout << endl;

    
    m.push_front(20); // Move insert,右值引用,更简单高效

    cout << "List contents after move insert:" << endl;
    for (const auto& num : m) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

 

5.2 pop_front 

void pop_front(); 是用于从 ist 的开头移除一个元素的成员函数。它会删除列表中的第一个元素,并且将列表的大小减小一个单位。

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m = {10,20,30,40,50};

    m.pop_front();

    for (auto e : m)
    {
        cout << e << " ";
    }
    cout << endl;


    return 0;
}

5.3  push_back

void push_back (const value_type& val); 是 list 容器的成员函数,用于在列表的末尾插入一个新元素。它接受一个常量引用作为参数,将传入的值插入到列表末尾

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m;

    m.push_back(2);
    m.push_back(4);
    m.push_back(6);
    m.push_back(8);
    m.push_back(10);


    for (auto e : m)
    {
        cout << e << " ";
    }
    cout << endl;


    return 0;
}

5.4 pop_back

void pop_back(); 是 list 容器的成员函数,用于删除列表中的最后一个元素。它会将列表的最后一个元素从容器中移除,同时释放相应的内存资源。

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m;

    m.push_back(2);
    m.push_back(4);
    m.push_back(6);
    m.push_back(8);
    m.push_back(10);

    m.pop_back();
    m.pop_back();


    list<int>::iterator it = m.begin();
    while (it != m.end())
    {
        cout<<*it<<" ";
        it++;
     }
    cout << endl;

    return 0;
}

 

 5.5 insert

在list position 位置中插入值为val的元素

iterator insert (iterator position, const value_type& val); 是 list 容器的成员函数,用于在指定位置插入一个新元素,新元素的值由 val 参数确定。

参数说明:

position:要插入新元素的位置的迭代器。
val:要插入的元素的值。
该函数返回一个迭代器,指向插入的元素。

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m = {1,2,3,4,5};

    auto a = m.begin();

    a++;   //begin的下一个位置,第二个位置

    m.insert(a,10);



    list<int>::iterator it = m.begin();
    while (it != m.end())
    {
        cout<<*it<<" ";
        it++;
     }
    cout << endl;

    return 0;
}


 

5.6. erase

删除list position位置的元素


iterator erase (iterator position); 和 iterator erase (iterator first, iterator last); 是 std::list 容器的成员函数,用于从列表中删除一个或多个元素。

iterator erase (iterator position); 删除指定位置的元素,并返回指向下一个元素的迭代器。

参数说明:

position:要删除的元素的位置的迭代器。
返回值:指向被删除元素之后的元素的迭代器。

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m = {1,2,3,4,5};

    auto a = m.begin();

    a++;   //begin的下一个位置,第二个位置

    m.erase(a);
}

5.7  swap 

交换两个list中的元素

#include<iostream>
#include<list>
using namespace std;

int main()
{
    list<int> m = {1,2,3,4,5};
    list<int> n = { 6,7,8,9,0};

    m.swap(n);


    list<int>::iterator it = m.begin();
    cout << "m:";;

    while (it != m.end())
    {
       
        cout << *it << " ";
        it++;
    }
    cout << endl;


    list<int>::iterator is = n.begin();
    cout << "n:";

    while (is != n.end())
    {
        cout << *is << " ";
        is++;
    }
    cout <<  endl;


    return 0;
}

5.8 clear 

清空list中的有效元素

#include<iostream>
#include<list>
using namespace std;

#include <iostream>
#include <list>

int main() {
   list<int> m = { 1, 2, 3, 4, 5 };

    cout << "m before clear: ";
    for (int num : m) {
        cout << num << " ";
    }
    cout << endl;

    m.clear(); // 清空列表

  cout << "m after clear: ";
    for (int num : m) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

 6.list操作函数

6.1. splice

void splice (iterator position, list& x);
该成员函数用于将另一个列表 x 中的所有元素移动到当前列表中,插入到指定位置 position 前。x 列表在移动后会变为空列表。

#include<iostream>
#include<list>
using namespace std;


int main() {
    list<int> m1 = { 1, 2, 3 };
    list<int> m2 = { 4, 5, 6 };

    auto it = m1.begin();
    advance(it,1); 

    m1.splice(it, m2); // 将 m2 的元素插入到 m1 中

    cout << "m1 after splice: ";
    for (int num : m1) {
        cout << num << " ";
    }
    cout << endl;

    cout << "m2 after splice: ";
    for (int num : m2) {
        cout << num << " ";
    }
     cout << endl;

    return 0;
}

6.2. remove

void remove (const value_type& val);
该成员函数用于从列表中移除所有等于给定值 val 的元素。

#include<iostream>
#include<list>
using namespace std;


int main() {
    list<int> m = { 1, 2, 3, 2, 4, 2, 5 };

    m.remove(2); // 移除列表中所有值为 2 的元素

    cout << "m after remove: ";
    for (int num : m) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

 

6.3. unique

void unique();
这个成员函数用于移除列表中相邻的重复元素。它只保留第一个出现的重复元素,移除后续的重复元素。

#include<iostream>
#include<list>
using namespace std;


int main() {
    list<int> m = { 1, 2, 2, 2, 3, 4,4, 5 };

    m.unique( ); // 移除列表中所有值为 2 的元素

    cout << "m after remove: ";
    for (int num : m) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

 

6.4. reverse

void reverse(); 函数用于将列表中的元素逆序排列。

#include<iostream>
#include<list>
using namespace std;


int main() {
    list<int> m = { 1, 2,3,4, 5 };

    m.reverse( ); // 移除列表中所有值为 2 的元素

    cout << "m after remove: ";
    for (int num : m) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

 7.list的迭代器失效

迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

当使用 std::list 进行删除操作时,可能会导致迭代器失效。下面是一个示例:

#include<iostream>
#include<list>
using namespace std;


int main() {
    list<int> m = { 1, 2, 3, 4, 5 };

    auto it = m.begin();
    ++it; // Move the iterator to the second element

    m.erase(it); // Erase the second element

    for (auto n : m) {
        cout << n << " ";
    }

    return 0;
}

在上面的示例中,当我们在第二个元素位置处使用 erase 函数删除元素后,迭代器 it 就会失效,因为它指向的元素已经被删除。如果我们尝试使用失效的迭代器,可能会导致未定义的行为

要修正这个问题,可以使用 erase 函数的返回值,它会返回一个指向下一个有效元素的迭代器:

#include<iostream>
#include<list>
using namespace std;


int main() {
    list<int> m = { 1, 2, 3, 4, 5 };

    auto it = m.begin();
    ++it; // Move the iterator to the second element

    it=m.erase(it); // Erase the second element

    for (auto n : m) {
        cout << n << " ";
    }

    return 0;
}


本文章借鉴了「爱学习的鱼佬」的原创文章,原文在下面链接
原文链接:https://blog.csdn.net/kingxzq/article/details/132225841

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

竞赛选题 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测

文章目录 0 简介1 基于 Keras 用 LSTM 网络做时间序列预测2 长短记忆网络3 LSTM 网络结构和原理3.1 LSTM核心思想3.2 遗忘门3.3 输入门3.4 输出门 4 基于LSTM的天气预测4.1 数据集4.2 预测示例 5 基于LSTM的股票价格预测5.1 数据集5.2 实现代码 6 lstm 预测航空旅客数目数据集预…

无需API开发,钱方QFPay连接营销系统和广告推广平台

随着电子商务市场的不断发展&#xff0c;企业需要集成各种业务系统&#xff0c;以提高业务效率和降低运营成本。钱方QFPay提供了一种创新的解决方案&#xff0c;帮助企业实现系统间的连接和集成&#xff0c;无需进行复杂的API开发。除了电商系统和客服系统&#xff0c;钱方还能…

c语言-浅谈指针(4)

文章目录 1.回调函数概念举例 2.qsort函数qsort的使用 3.通过冒泡排序来模拟qsort函数排序int类型排序结构体类型 这是指针最后一篇了喔&#xff0c;完结撒花 ! 前三篇&#xff1a; 浅谈指针&#xff08;1&#xff09;http://t.csdnimg.cn/JTRjW 浅谈指针&#xff08;2&#xf…

企业远程访问业务系统:对比MPLS专线,贝锐蒲公英为何更优优势?

如今&#xff0c;企业大多都会采用OA、ERP、CRM等各种数字化业务系统。 私有云、公有云混合架构也变得越来越常见。 比如&#xff1a;研发系统部署在公司本地私有云、确保数据安全&#xff0c;OA采用公有云方案、满足随时随地访问需求。 如此一来&#xff0c;也产生了远程访问…

【分布式】分布式事务及其解决方案

目录 一、分布式事务二、分布式事务的解决方案1. 全局事务&#xff08;1&#xff09;DTP模型&#xff08;2&#xff09; 两阶段提交协议&#xff08;2PC&#xff09;原理二阶段提交的缺点 &#xff08;3&#xff09;三阶段提交协议&#xff08;3PC&#xff09;原理 2. 基于可靠…

ModuleNotFoundError: No module named ‘torch_sparse‘

1、卸载 先把torch-geometric、torch-sparse、torch-scatter、torch-cluster、 torch-spline-conv全部卸载了 pip uninstall torch-geometric torch-scatter torch-sparse torch-cluster torch-spline-conv 2.conda list确定PyTorch的版本&#xff0c;我的是1.10 3、确定下载地…

Excel表中合并两个Sheet的方法?

按AltF11&#xff0c;调出Visual Basic 界面。 在左侧窗口中&#xff0c;右键选择“插入”—“模块”&#xff1a; 将如下代码粘贴进去&#xff0c;点击运行按钮&#xff0c;完成数据表合并。 Sub MergeAllSheetsInThisWorkbook() On Error Resume Next Application.ScreenU…

38 关于 redo 日志

前言 undo 和 redo 是在 mysql 中 事务, 或者 异常恢复 的场景下面 经常会看到的两个概念 这里 来看一下 redo, redo 主要是用于 异常恢复 的场景下面 测试表结构如下 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(128) DEFAULT NULL…

通过线性回归进行房价预测

房价预测一直是房地产行业和投资者关注的重要问题。线性回归是一种常用的回归算法&#xff0c;可以建立输入变量和连续输出变量之间的关系。在本文中&#xff0c;我们将探讨如何使用线性回归算法来进行房价预测&#xff0c;并介绍该方法的步骤和实践技巧。 一、线性回归算法简…

拼图游戏制作

1.创建4个包 2.创建用户界面 package domain;/*** ClassName: User* Author: Kox* Data: 2023/2/2* Sketch:*/ public class User {private String username;private String password;public User() {}public User(String username, String password) {this.username usernam…

浅谈 Binius:用 Rust 实现的硬件优化 SNARK 协议

作者&#xff1a;Ulvetanna 团队 编译&#xff1a;TinTinLand 原文链接&#xff1a;https://www.ulvetanna.io/news/binius-hardware-optimized-snark 在一篇新的研究论文中&#xff0c;零知识证明技术开发团队 Ulvetanna 展示了一种基于二进制域塔 &#xff08;Towers of Bi…

迪科DTC-F81收费机DTC-F82

迪科DTC-F81收费机是一款挂式收费机&#xff0c;广泛应用的学校食堂刷卡消费&#xff0c;DTC-F82收费机是台式消费机&#xff0c;常用在学校超市&#xff0c;放在桌子上使用的&#xff0c;这2款消费机是迪科畅销机型&#xff0c;如下图 机器质量可靠稳定&#xff0c;不少用户使…

NFT Insider115:The Sandbox开设元宇宙Diorama快闪店,​YGG Web3 游戏峰会已开幕

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members、BeepCrypto联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周报将从NFT市场数据&#xff0c;艺术新闻类&#xff0c;游戏新闻类&#xff0c;虚拟世界类&#…

Vue3框架中让table合计居中对齐

第一步&#xff1a;给它加一个类名 center-table 如下&#xff1a; <el-table:data"datas.shows"max-height"600px"show-summarystripeborderstyle"width: 100%":header-cell-style"{ textAlign: center }":cell-style"{ text…

threejs创建一个旋转的正方体【完整代码】

效果&#xff1a; 中文网three.js docs 1.搭建环境 安装three 首先我们需要新建一个项目 vue/react都可 这里以vue为演示 npm i three 找到一个新的页面 在页面script的地方导入three import * as THREE from "three" 或者自己逐个导入 import {PerspectiveC…

SQLite 和 SQLiteDatabase 的使用

实验七&#xff1a;SQLite 和 SQLiteDatabase 的使用 7.1 实验目的 本次实验的目的是让大家熟悉 Android 中对数据库进行操作的相关的接口、类等。SQLiteDatabase 这个是在 android 中数据库操作使用最频繁的一个类。通过它可以实现数据库的创建或打开、创建表、插入数据、删…

保姆级 ARM64 CPU架构下安装部署Docker + rancher + K8S 说明文档

1 K8S 简介 K8S是Kubernetes的简称&#xff0c;是一个开源的容器编排平台&#xff0c;用于自动部署、扩展和管理“容器化&#xff08;containerized&#xff09;应用程序”的系统。它可以跨多个主机聚集在一起&#xff0c;控制和自动化应用的部署与更新。 K8S 架构 Kubernete…

【nlp】3.6 Tansformer模型构建(编码器与解码器模块耦合)

Tansformer模型构建(编码器与解码器模块耦合) 1. 模型构建介绍2 编码器-解码器结构的代码实现3 Tansformer模型构建过程的代码实现4 小结1. 模型构建介绍 通过上面的小节, 我们已经完成了所有组成部分的实现, 接下来就来实现完整的编码器-解码器结构耦合. Transformer总体架…

聚类笔记:HDBSCAN

1 算法介绍 DBSCAN/OPTICS层次聚类主要由以下几步组成 空间变换构建最小生成树构建聚类层次结构(聚类树)压缩聚类树提取簇 2 空间变换 用互达距离来表示两个样本点之间的距离 ——>密集区域的样本距离不受影响——>稀疏区域的样本点与其他样本点的距离被放大——>…

Unity Android FireBase bugly报错查询

报错如下图&#xff0c;注意&#xff0c;标红的三处 使用的il2cpp和架构是arm64-v8a 那我们就可以根据这些去找对应的符号表&#xff0c;在unity安装目录下 Unity2020.3.33f1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Symbols\arm64-v8a 找到l…