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

list的使用,及部分功能的模拟实现(C++)

目录(文章中"节点"和"结点"是同一个意思)

1. list的介绍及使用

1.1 list的介绍

1.2 list的使用

1.2.1 list的构造

 1.2.2 list iterator的使用

 1.2.3 list capacity

1.2.4 list element access

 1.2.5 list modifiers

 1.2.6 list的迭代器失效

 2. list的模拟实现

2.1 list_node结点

 2.2 list_iterator迭代器

 2.2.1 运算符重载!=

2.2.2  运算符重载==

 2.2.3 运算符重载前置++

 2.2.4 运算符重载后置++

 2.2.5 运算符重载前置--

 2.2.6 运算符重载后置--

 2.2.7 运算符重载*

 2.2.8 运算符重载->

 2.3 list类

2.3.1 构造函数

2.3.1.1默认构造函数list

 2.3.1.2 拷贝构造

2.3.1.3  list(std::initializer_list lt)

 2.3.2 析构函数

2.3.3 赋值运算符重载

 2.3.4 front和back

2.3.5 size和begin和end

2.3.6 insert插入和erase删除

2.3.6.1 insert插入

 2.3.6.2 erase删除

2.3.7 头插push_front,头删pop_front,尾插push_back,尾删pop_back

2.4 整体代码

1. list的介绍及使用

1.1 list的介绍

std::list是 C++ 标准模板库(STL)中的一个容器类,底层实现为双向链表,适用于需要频繁插入和删除操作的场景。

1.2 list的使用

以下为list中一些常见的重要接口。

1.2.1 list的构造

构造函数( (constructor))接口说明
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)用[first, last)区间中的元素构造 list

使用演示:

void test1()
{list<int> l1(10, 5);list<int> l2;list<int> l3(l1);list<int> l4(l1.begin(),l1.end());for (auto& e : l1){cout << e << " ";}cout << endl;for (auto& e : l2){cout << e << " ";}cout << endl;for (auto& e : l3){cout << e << " ";}cout << endl;	for (auto& e : l4){cout << e << " ";}cout << endl;
}

结果:

 1.2.2 list iterator的使用

这里可以暂时将迭代器理解成一个指针,该指针指向list中的某个节点。(其实底层实现时,迭代器是一个封装的对象

函数声明接口说明
begin + end返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin + rend返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位 置的reverse_iterator,即begin位置

1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

使用演示:

void test2()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);list<int>::reverse_iterator rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";rit++;}cout << endl;list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";it++;}cout << endl;
}

结果:

 1.2.3 list capacity

函数声明接口说明
empty检测list是否为空,是返回true,否则返回false
size返回list中有效节点的个数

使用演示:

void test3()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);if(!l.empty()){cout << "该链表非空" << endl;}cout << "有效节点个数:" << l.size() << endl;
}

结果:

1.2.4 list element access

函数声明接口说明
front返回list的第一个节点中值的引用
back返回list的最后一个节点中值的引用

 使用演示:

void test4()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);cout << l.front() << endl;cout << l.back() << endl;
}

结果:

 1.2.5 list modifiers

函数声明接口说明
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中的有效元素

使用演示:

push_front和pop_front使用:

void test5()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);for (auto& e : l){cout << e << " ";}cout << endl;l.push_front(10);cout << "头插后:";for (auto& e : l){cout << e << " ";}cout << endl;l.pop_front();cout << "头删后:";for (auto& e : l){cout << e << " ";}cout << endl;
}

结果:

 push_back和pop_back:

void test6()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);for (auto& e : l){cout << e << " ";}cout << endl;l.push_back(6);cout << "尾插后:";for (auto& e : l){cout << e << " ";}cout << endl;l.pop_back();cout << "尾删后:";for (auto& e : l){cout << e << " ";}cout << endl;
}

结果:

 insert和erase:

void test7()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);for (auto& e : l){cout << e << " ";}cout << endl;l.insert(++l.begin(), 30);cout << "插入后:";for (auto& e : l){cout << e << " ";}cout << endl;l.erase(--l.end());cout << "删除后:";for (auto& e : l){cout << e << " ";}cout << endl;
}

结果:

swap:

void test8()
{list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);list<int> l2(5, 5);cout << "交换前" << endl;cout << "l1:";for (auto& e : l1){cout << e << " ";}cout << endl;cout << "l2:";for (auto& e : l2){cout << e << " ";}cout << endl;cout << "交换后" << endl;l1.swap(l2);cout << "l1:";for (auto& e : l1){cout << e << " ";}cout << endl;cout << "l2:";for (auto& e : l2){cout << e << " ";}cout << endl;
}

 结果:

clear:

void test9()
{list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);cout << "清空前" << endl;cout << "有效元素个数:" << l1.size() << endl;for (auto& e : l1){cout << e << " ";}cout << endl;l1.clear();cout << "清空后" << endl;cout << "有效元素个数:" << l1.size() << endl;for (auto& e : l1){cout << e << " ";}cout << endl;
}

 结果:

 1.2.6 list的迭代器失效

小编前面文章里面“vector迭代器失效”,提到只要使用erase或者insert之后迭代器就直接失效,但是对于list有所不同,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

 举例(删除所有结点):

void test10()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值l.erase(it);++it;}
}

结果:

可以看到这里报段错误,迭代器失效了。

改进后:

void test10()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){it=l.erase(it);}
}

因为erase函数删除后,会返回删除结点的下一个节点迭代器,it接收返回值,相当于更新了迭代器。

 2. list的模拟实现

这里利用双向带头链表实现,因为链表的物理空间并不是连续的,所以这里的迭代器不能使用指针,这里对迭代器进行了封装,实现一个对象。还有这里为了和原本库里list区分,将自己写的list封装在命名空间里(作者的是iu)

2.1 list_node结点

template<class T>
struct list_node
{list_node<T>* _prev;list_node<T>* _next;T _value;list_node(const T& x = T()):_prev(nullptr),_next(nullptr),_value(x){}
};

双向带头链表,所以成员有前驱结点,和后继结点,和元素对象。

 2.2 list_iterator迭代器

template<class T,class REF,class PTR>
struct list_iterator
{typedef list_node<T> Node;typedef list_iterator<T, REF, PTR> Self;Node* _node;list_iterator(Node* node):_node(node){}};

这里模版为什么会有REF和PTR?其实是解决,范围for迭代器访问时,会有const修饰的对象,如果直接确定的写,只有普通对象可以,所以这里多给两个参数模版,让编译器自己去判断是const修饰的对象,还是普通对象。

 2.2.1 运算符重载!=

bool operator!=(const Self& it)
{return  _node!=it._node;
}

2.2.2  运算符重载==

bool operator==(const Self& it)
{return _node == it._node;
}

 2.2.3 运算符重载前置++

Self& operator++()
{_node = _node->_next;return *this;
}

结点的指向直接向后移动一位。

 2.2.4 运算符重载后置++

Self operator++(int)
{Self tmp(*this);_node = _node->_next;return tmp;
}

创建一个临时对象,节点的指向向后移动一位,返回临时对象。

 2.2.5 运算符重载前置--

Self& operator--()
{_node = _node->_prev;return *this;
}

结点的指向直接向前移动一位。

 2.2.6 运算符重载后置--

Self operator++(int)
{Self tmp(*this);_node = _node->_next;return tmp;
}

创建一个临时对象,节点的指向向前移动一位,返回临时对象。

 2.2.7 运算符重载*

REF operator*()
{return _node->_value;
}

解引用,就是返回对象的值。

 2.2.8 运算符重载->

PTR operator->()
{return &_node->_value;
}

这里为什么是取值的地址?通过下面的例子来讲解:

void test2()
{struct A{A(int a = 0,int b=0):_a(a),_b(b){}int _a;int _b;};iu::list<A>l2;l2.push_back({1,1});l2.push_back({2,2});l2.push_back({3,3});l2.push_back({4,4});iu::list<A>::iterator it = l2.begin();while (it != l2.end()){cout << (*it)._a << ":" << it->_b << endl;it++;}
}

这里可以利用解引用在去访问,A类中的成员,这是一种访问方式;而这个it->b是如何访问的?前面实现的是返回A的地址,拿到A对象的地址和成员_b之间也没有运算符,那有怎么样才能访问到_b呢?其实这里省略了一个->,这里其实应该是it->->_b,所以先拿到A对象的地址,再利用结构体->这种方式。解引用访问里面的成员。

结果:

 2.3 list类

	template<class T>class list{typedef list_node<T> Node;public:typedef list_iterator<T,T&,T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;private:Node* _head;size_t _size;};
}

成员有头结点,和元素个数。

2.3.1 构造函数

2.3.1.1默认构造函数list
void empty_init()
{_head = new Node;_head->_prev = _head;_head->_next = _head;_size = 0;
}list()
{empty_init();
}

这里利用empty_init函数,进行初始化,是为了方便后面几个构造函数,先初始化,再尾插的操作。

 2.3.1.2 拷贝构造
list(const list<T>& lt)
{empty_init();for (auto& e : lt){push_back(e);}
}

初始化,再遍历一遍lt,进行尾插依次插入。

2.3.1.3  list(std::initializer_list<T> lt)
list(std::initializer_list<T> lt)
{empty_init();for (auto& e : lt){push_back(e);}
}

和上面同理。

这里举一个例子:

void test8()
{iu::list<int>l1 = { 1,2,3,4,5,6,7 };for (auto& e : l1){cout << e << " ";}cout << endl;
}

 结果:

这个initializer_list<T>类型是一个类似于数组的类型,可以理解成一种类似数组初始化的方式。

 2.3.2 析构函数

void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}~list()
{clear();delete _head;_head = nullptr;
}

先在clear函数里面将数据全部清除,再将头结点释放掉,置为空。

2.3.3 赋值运算符重载

void swap(list<T>& lt)
{std::swap(_head, lt._head);std::swap(_size, lt._size);
}list<T>& operator=(list<T> lt)
{swap(lt);return *this;
}

 利用std中的交换函数,将临时对象与this指向的对象进行交换,临时对象出了作用域会自然销毁,也不会影响实参,这样就相当于实现了赋值操作。

 2.3.4 front和back

T& front()
{return _head->_next->_value;
}const T& front()const
{return _head->_next->_value;
}
T& back()
{return _head->_prev->_value;
}
const T& back()const
{return _head->_prev->_value;
}

这里利用的是双向带头链表,所以头部front元素就是头结点的下一个,尾结点back就是头结点的前一个。这里还重载了const修饰的对象,当对象元素是不可改变的const时,也可以使用。

2.3.5 size和begin和end

size_t size()
{return _size;
}iterator begin()
{return _head->_next;
}iterator end()
{return _head;
}const_iterator begin() const
{return _head->_next;
}const_iterator end() const
{return _head;
}		

size函数,直接返回成员_size大小即可。

begin()返回头结点的下一个结点的迭代器,end()返回最后一个元素的下一个结点的迭代器,所以就是头结点head,这里也是重载了const修饰的对象,当对象元素是不可改变的const时,也可以使用。

2.3.6 insert插入和erase删除

2.3.6.1 insert插入
void insert(iterator pos,const T& x)
{Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;
}

首先创建一个新的结点,再进行插入操作,插入时,先找到pos位置的结点,和pos位置的前一个结点,再改变前后指针指向即可,最后_size再加1。

 2.3.6.2 erase删除
iterator erase(iterator pos)
{assert(pos != end());Node* del = pos._node;Node* prev = del->_prev;Node* next = del->_next;prev->_next = next;next->_prev = prev;delete del;--_size;return iterator(next);
}

首先找到pos位置的结点,再确定pos前一个结点,和后一个结点的位置,最后改变指针指向,再删除pos位置的节点,_size再减1,最后还要返回删除节点的下一个位置的结点,返回匿名对象即可。

2.3.7 头插push_front,头删pop_front,尾插push_back,尾删pop_back

void push_back(const T& x)
{insert(end(), x);
}
void push_front(const T& x)
{insert(begin(), x);
}
void pop_back()
{erase(--end());
}void pop_front()
{erase(begin());
}

这里直接复用insert和erase函数实现,只是要注意尾结点的位置是end()的前一个位置。

 例子:

void test4()
{iu::list<int>l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.insert(l1.begin(), 10);l1.insert(l1.begin(), 20);for (auto& e : l1){cout << e << " ";}cout << endl;l1.pop_back();l1.pop_back();l1.pop_front();l1.pop_front();for (auto& e : l1){cout << e << " ";}cout << endl;
}

结果:

2.4 整体代码

#include<assert.h>
#include<algorithm>
#include <initializer_list>namespace iu
{template<class T>struct list_node{list_node<T>* _prev;list_node<T>* _next;T _value;list_node(const T& x = T()):_prev(nullptr),_next(nullptr),_value(x){}};template<class T,class REF,class PTR>struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, REF, PTR> Self;Node* _node;list_iterator(Node* node):_node(node){}bool operator!=(const Self& it){return  _node!=it._node;}bool operator==(const Self& it){return _node == it._node;}REF operator*(){return _node->_value;}PTR operator->(){return &_node->_value;}Self& operator++(){_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}};template<class T>class list{typedef list_node<T> Node;public:typedef list_iterator<T,T&,T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;void empty_init(){_head = new Node;_head->_prev = _head;_head->_next = _head;_size = 0;}list(){empty_init();}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}list<T>& operator=(list<T> lt){swap(lt);return *this;}list(std::initializer_list<T> lt){empty_init();for (auto& e : lt){push_back(e);}}list(const list<T>& lt)//拷贝构造{empty_init();for (auto& e : lt){push_back(e);}}~list(){clear();delete _head;_head = nullptr;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}T& front(){return _head->_next->_value;}const T& front()const{return _head->_next->_value;}T& back(){return _head->_prev->_value;}const T& back()const{return _head->_prev->_value;}size_t size(){return _size;}iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void push_back(const T& x){//Node* newnode = new Node(x);//Node* tail = _head->_prev;//newnode->_prev = tail;//tail->_next = newnode;//newnode->_next = _head;//_head->_prev = newnode;insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void insert(iterator pos,const T& x){Node* newnode = new Node(x);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;}iterator erase(iterator pos){assert(pos != end());Node* del = pos._node;Node* prev = del->_prev;Node* next = del->_next;prev->_next = next;next->_prev = prev;delete del;--_size;return iterator(next);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}private:Node* _head;size_t _size;};
}

相关文章:

list的使用,及部分功能的模拟实现(C++)

目录&#xff08;文章中"节点"和"结点"是同一个意思&#xff09; 1. list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list…...

联想Y7000+RTX4060+i7+Ubuntu22.04运行DeepSeek开源多模态大模型Janus-Pro-1B+本地部署

直接上手搓了&#xff1a; conda create -n myenv python3.10 -ygit clone https://github.com/deepseek-ai/Janus.gitcd Januspip install -e .pip install webencodings beautifulsoup4 tinycss2pip install -e .[gradio]pip install pexpect>4.3python demo/app_januspr…...

[Spring] Gateway详解

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…...

音叉模态分析

目录 0 序言 1 自由状态下模态求解 1.1 添加模态项目 1.2 生成网格 1.3 设置最大模态阶数 1.4 求解 1.5 结果查看 1.6 结果分析 2 音叉能否释放频率440Hz的音调 3 预应力模态求解 3.1 静态结构分析 3.1.1 添加静态结构项目 3.1.2生成网格 3.1.3添加边界条件 3.1…...

BW AO/工作簿权限配置

场景&#xff1a; 按事业部配置工作簿权限&#xff1b; 1、创建用户 事务码&#xff1a;SU01&#xff0c;用户主数据的维护&#xff0c;可以创建、修改、删除、锁定、解锁、修改密码等 用户设置详情页 2、创建权限角色 用户的权限菜单是通过权限角色分配来实现的 2.1、自定…...

C++ 字母大小写转换两种方法统计数字字符的个数

目录 题目&#xff1a; 代码1&#xff1a; 代码2&#xff1a; 题目描述输入一行字符&#xff0c;统计出其中数字字符的个数。 代码如下&#xff1a; 判断⼀个字符是否是数字字符有⼀个函数是 isdigit ,可以直接使⽤。 代码如下&#xff1a; 题目&#xff1a; 大家都知道…...

如何使用 ChatBox AI 简化本地模型对话操作

部署模型请看上一篇帖子&#xff1a;本地部署DeepSeek教程&#xff08;Mac版本&#xff09;-CSDN博客 使用 ChatBox AI 简化本地模型对话操作&#xff1a; 打开 ChatBox AI 官网&#xff1a;Chatbox AI官网&#xff1a;办公学习的AI好助手&#xff0c;全平台AI客户端&#xf…...

前端面试笔试题目(一)

以下模拟了大厂前端面试流程&#xff0c;并给出了涵盖HTML、CSS、JavaScript等基础和进阶知识的前端笔试题目&#xff0c;以帮助你更好地准备面试。 面试流程模拟 1. 自我介绍&#xff08;5 - 10分钟&#xff09;&#xff1a;面试官会请你进行简单的自我介绍&#xff0c;包括…...

Docker Hello World

Docker Hello World 引言 Docker 是一个开源的应用容器引擎,可以让开发者打包他们的应用以及应用的依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。本文将带领您从零开始,学习如何使用 Docker 运行一个简单的 "Hello World"…...

UE 5.3 C++ 对垃圾回收的初步认识

一.UObject的创建 UObject 不支持构造参数。 所有的C UObject都会在引擎启动的时候初始化&#xff0c;然后引擎会调用其默认构造器。如果没有默认的构造器&#xff0c;那么 UObject 将不会编译。 有修改父类参数的需求&#xff0c;就使用指定带参构造 // Sets default value…...

ARM内核:嵌入式时代的核心引擎

引言 在当今智能设备无处不在的时代&#xff0c;ARM&#xff08;Advanced RISC Machines&#xff09;处理器凭借其高性能、低功耗的特性&#xff0c;成为智能手机、物联网设备、汽车电子等领域的核心引擎。作为精简指令集&#xff08;RISC&#xff09;的典范&#xff0c;ARM核…...

需求分析应该从哪些方面来着手做?

需求分析一般可从以下几个方面着手&#xff1a; 业务需求方面 - 与相关方沟通&#xff1a;与业务部门、客户等进行深入交流&#xff0c;通过访谈、问卷调查、会议讨论等方式&#xff0c;明确他们对项目的期望、目标和整体业务需求&#xff0c;了解项目要解决的业务问题及达成的…...

【Unity2D 2022:C#Script】DoTween插件的使用

一、插件介绍 DOTween 是一个快速、高效、完全类型安全的 Unity 面向对象的动画引擎&#xff0c;针对 C# 用户进行了优化&#xff0c;免费和开源&#xff0c;具有大量高级功能 二、插件的下载 1. DoTween官网&#xff1a;DOTween (HOTween v2) 2. DoTween下载&#xff1a; …...

【Docker】ubuntu中 Docker的使用

之前记录了 docker的安装 【环境配置】ubuntu中 Docker的安装&#xff1b; 本篇博客记录Dockerfile的示例&#xff0c;docker 的使用&#xff0c;包括镜像的构建、容器的启动、docker compose的使用等。   当安装好后&#xff0c;可查看docker的基本信息 docker info ## 查…...

【数据结构篇】时间复杂度

一.数据结构前言 1.1 数据结构的概念 数据结构(Data Structure)是计算机存储、组织数据的⽅式&#xff0c;指相互之间存在⼀种或多种特定关系的数 据元素的集合。没有⼀种单⼀的数据结构对所有⽤途都有⽤&#xff0c;所以我们要学各式各样的数据结构&#xff0c; 如&#xff1a…...

linux 环境安装 dlib 的 gpu 版本

默认使用 pip 安装的 dlib 是不使用 gpu 的 在国内社区用百度查如何安装 gpu 版本的 dlib 感觉信息都不太对&#xff0c;都是说要源码编译还有点复杂 还需要自己安装 cuda 相关的包啥的&#xff0c;看着就头大 于是想到这个因该 conda 自己就支持了吧&#xff0c;然后查了一下…...

springboot集成钉钉,发送钉钉日报

目录 1.说明 2.示例 3.总结 1.说明 学习地图 - 钉钉开放平台 在钉钉开放文档中可以查看有关日志相关的api&#xff0c;主要用到以下几个api&#xff1a; ①获取模板详情 ②获取用户发送日志的概要信息 ③获取日志接收人员列表 ④创建日志 发送日志时需要根据模板规定日志…...

【机器学习】自定义数据集 使用scikit-learn中svm的包实现svm分类

一、支持向量机(support vector machines. &#xff0c;SVM)概念 1. SVM 绪论 支持向量机&#xff08;SVM&#xff09;的核心思想是找到一个最优的超平面&#xff0c;将不同类别的数据点分开。SVM 的关键特点包括&#xff1a; ① 分类与回归&#xff1a; SVM 可以用于分类&a…...

快速提升网站收录:利用网站历史数据

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/38.html 利用网站历史数据可以有效提升网站的收录速度&#xff0c;以下是一些具体的策略和方法&#xff1a; 一、理解网站历史数据的重要性 网站历史数据记录了网站过去的运营情况、用户行…...

【Git】初识Git Git基本操作详解

文章目录 学习目标Ⅰ. 初始 Git&#x1f4a5;注意事项 Ⅱ. Git 安装Linux-centos安装Git Ⅲ. Git基本操作一、创建git本地仓库 -- git init二、配置 Git -- git config三、认识工作区、暂存区、版本库① 工作区② 暂存区③ 版本库④ 三者的关系 四、添加、提交更改、查看提交日…...

Elsevier Tracker:告别投稿焦虑,3分钟实现学术稿件智能追踪

Elsevier Tracker&#xff1a;告别投稿焦虑&#xff0c;3分钟实现学术稿件智能追踪 【免费下载链接】Elsevier-Tracker 项目地址: https://gitcode.com/gh_mirrors/el/Elsevier-Tracker 还在为Elsevier投稿后的漫长等待而焦虑吗&#xff1f;每天反复登录系统查看审稿状…...

Android BLE开发实战:从BlueDroid扫描流程到性能调优全解析(附代码示例)

Android BLE开发深度优化&#xff1a;从BlueDroid扫描机制到实战性能调优 1. 理解BLE扫描的核心机制 在Android蓝牙低功耗&#xff08;BLE&#xff09;开发中&#xff0c;扫描机制是连接设备的第一步&#xff0c;也是最容易出现性能瓶颈的环节。与传统的蓝牙扫描不同&#xff0…...

告别布局跳动!Android Dialog+EditText+软键盘的终极适配指南(含Kotlin代码)

Android Dialog软键盘适配全攻略&#xff1a;从布局跳动到完美交互 在Android开发中&#xff0c;Dialog与软键盘的交互一直是让开发者头疼的问题。当EditText获得焦点时&#xff0c;弹出的软键盘经常会遮挡输入框或导致布局跳动&#xff0c;严重影响用户体验。本文将深入探讨Di…...

SPIRAN ART SUMMONER异常处理:常见错误解决方案

SPIRAN ART SUMMONER异常处理&#xff1a;常见错误解决方案 1. 前言 遇到SPIRAN ART SUMMONER运行报错时&#xff0c;别急着放弃。作为一款强大的AI艺术生成工具&#xff0c;它在使用过程中确实会遇到一些典型问题&#xff0c;但大多数都有明确的解决方法。本文汇总了用户反馈…...

Qwen3-1.7B推理模式切换体验:思考模式与非思考模式效果对比

Qwen3-1.7B推理模式切换体验&#xff1a;思考模式与非思考模式效果对比 1. 引言&#xff1a;双模式推理的创新价值 在边缘计算和轻量化AI模型快速发展的今天&#xff0c;Qwen3-1.7B通过独特的动态双模式架构&#xff0c;为用户提供了灵活的推理选择。这款17亿参数的轻量级大语…...

【Linux】深入理解进程调度:从nice值到实时优先级(RT Priority)的进阶指南

1. Linux进程调度基础&#xff1a;从nice值说起 第一次接触Linux进程调度时&#xff0c;我被那个叫"nice值"的概念搞懵了。为什么用"nice"这个词&#xff1f;后来才明白&#xff0c;这个命名其实很形象——越"nice"的进程越谦让&#xff0c;愿意…...

现在不升级Polars 2.0清洗栈,你的ETL将在Q3面临300%延迟增长——基于AWS Graviton+Arrow 15.0实测基准报告

第一章&#xff1a;Polars 2.0清洗栈升级的必要性与Q3延迟危机预警Polars 2.0 的清洗栈重构并非功能叠加式演进&#xff0c;而是面向真实数据工程场景的范式重置。随着企业级ETL流水线中非结构化日志、嵌套JSON、时序传感器数据占比突破68%&#xff0c;旧版基于LazyFrame单通道…...

西门子博图V16实战:5种工作模式机械手PLC程序全解析(附HMI组态文件)

西门子博图V16实战&#xff1a;5种工作模式机械手PLC程序全解析&#xff08;附HMI组态文件&#xff09; 在工业自动化领域&#xff0c;机械手控制系统一直是核心难点之一。如何实现多工作模式的灵活切换、确保信号互锁安全可靠&#xff0c;是每个PLC程序员必须掌握的技能。本文…...

写作压力小了!2026年首选推荐的专业降AI率软件

2026年论文降AI率工具已从“基础改写”升级为智能优化系统&#xff0c;核心评价维度包括AIGC识别精度、文本自然度、学术合规性、查重适配性、多语言支持与操作便捷性。本次测评覆盖6款主流工具&#xff0c;涵盖中英文论文、全流程与专项功能、免费与付费版本&#xff0c;让你高…...

Mojo调用Python生态的7种方式,第4种连PyTorch官方文档都没写!——混合编程兼容性白皮书首发

第一章&#xff1a;Mojo与Python混合编程全景概览Mojo 是一种兼具 Python 语法亲和力与系统级性能的现代编程语言&#xff0c;专为 AI 基础设施和高性能计算场景设计。它原生兼容 Python 生态&#xff0c;允许开发者在同一个项目中无缝调用 Python 模块、复用 NumPy/Torch 接口…...