list模拟实现【引入反向迭代器】
文章目录
- 1.适配器
- 1.1传统意义上的适配器
- 1.2语言里的适配器
- 1.3理解
- 2.list模拟实现【注意看反向迭代器】
- 2.1 list_frame.h
- 2.2riterator.h
- 2.3list.h
- 2.4 vector.h
- 2.5test.cpp
- 3.反向迭代器的应用
- 1.使用要求
- 2.迭代器的分类
1.适配器
1.1传统意义上的适配器


1.2语言里的适配器
- 容器适配器,如下:



- 迭代器适配器【以下会讲】
- 函数适配器【以后会讲】
1.3理解
所谓适配器,其实就是通过C++STL泛型编程的特性,使用模板参数实例化出不同的实体供调用者使用。根据传参实例化出不同实体的过程类似实际生活中的适配器【电源适配器可以转换不同伏特的电流供接收者使用】
例如:程序员实现了一个反向迭代器 在使用vector、list、map时可以将本身的正向迭代器传给模板参数
这样不用在每次用一个新的容器时 重复写反向迭代器 通过模板实例化 增强代码复用性
2.list模拟实现【注意看反向迭代器】

2.1 list_frame.h
namespace Apex
{//结点类template<class T>struct list_node{//成员变量T _data;list_node<T>* _next;list_node<T>* _prev;//成员函数//构造函数list_node(const T& data = T());};//迭代器类template<class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> iterator;typedef T value_type;typedef Ref reference;typedef Ptr pointer;//成员变量Node* _node;//成员函数//构造函数__list_iterator(Node* node);//解引用运算符重载Ref operator*();//成员访问符重载Ptr operator->();//前置++iterator& operator++();//后置++iterator operator++(int);//前置--iterator& operator--();//后置--iterator operator--(int);//关系运算符bool operator==(const iterator& it);bool operator!=(const iterator& it);};//链表类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;typedef __reverse_iterator<iterator, T&, T*> riterator;typedef __reverse_iterator<const_iterator, const T&, const T*> const_riterator;//成员函数//迭代器函数iterator begin();const_iterator begin() const;iterator end();const_iterator end() const;riterator rbegin();const_riterator rbegin() const;riterator rend();const_riterator rend() const;//无参构造函数list();//有参构造函数(初始化n个结点)list(size_t n, const T& val = T());//迭代器构造函数template<class InputIterator>list(InputIterator first, InputIterator last);//清空链表数据void clear();//析构函数~list();//拷贝构造list(const list<T>& lt);//赋值重载list<T>& operator=(list<T> lt);//pos前插入void insert(iterator pos, const T& x);//删除pos处数据iterator erase(iterator pos);//尾插void push_back(const T& x);//头插void push_front(const T& x);//尾删void pop_back();//头删void pop_front();private:Node* _head;};
}
2.2riterator.h
#pragma oncenamespace apex
{template<class Iterator, class Ref, class Ptr>struct __reverse_iterator{Iterator _cp;typedef __reverse_iterator<Iterator, Ref, Ptr> riterator;typedef Iterator value_type;typedef Ref reference;typedef Ptr pointer;//构造函数__reverse_iterator(Iterator it):_cp(it){}//解引用运算符重载Ref operator*(){auto tmp = _cp;return *--tmp;}//成员访问符重载Ptr operator->(){return &(operator*()); //return --_cp.operator->();}//前置++riterator operator++(){--_cp;return *this;}//后置++riterator operator++(int) {riterator tmp(*this);--_cp;return tmp;}//前置--riterator operator--(){++_cp;return *this;}//后置--riterator operator--(int){riterator tmp(*this);++_cp;return tmp;}//关系运算符bool operator==(const riterator& it){return _cp == it._cp;}bool operator!=(const riterator& it){return _cp != it._cp;}};
}
2.3list.h
#include <iostream>
#include <assert.h>
#include "riterator.h"
using namespace std;namespace apex
{//公有类--结点template<class T>struct list_node{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& data = T()): _data(data), _next(nullptr), _prev(nullptr){}};//迭代器类template<class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> iterator;typedef T value_type;typedef Ref reference;typedef Ptr pointer;//成员属性 _nodeNode* _node;//成员函数 //构造函数__list_iterator(Node* node): _node(node){}//解引用运算符重载Ref operator*(){return _node->_data;}//成员访问符重载Ptr operator->(){return &(operator*());//return &_node->_data;}//前置++iterator& operator++() //__list_iterator<T, Ref, Ptr>& operator++() { } {_node = _node->_next;return *this;}//后置++iterator operator++(int) //__list_iterator<T, Ref, Ptr> operator++(int) { }{iterator tmp(*this);_node = _node->_next;return tmp;}//前置--iterator& operator--(){_node = _node->_prev;return *this;}//后置--iterator operator--(int){iterator tmp(*this);_node = _node->_prev;return tmp;}//关系运算符bool operator==(const iterator& it){return _node == it._node;}bool operator!=(const iterator& it){return _node != it._node;}};//class类--链表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;typedef __reverse_iterator<iterator, T&, T*> riterator;typedef __reverse_iterator<const_iterator, const T&, const T*> const_riterator;//迭代器函数iterator begin(){return iterator(_head->_next);}iterator end(){return iterator(_head);}const_iterator begin() const{return const_iterator(_head->_next);}const_iterator end() const{return const_iterator(_head);}//反向迭代器函数riterator rbegin(){return riterator(end());}riterator rend(){return riterator(begin());}const_riterator rbegin() const{return const_riterator(end());}const_riterator rend() const{return const_riterator(begin());}//无参构造函数list(){_head = new Node();_head->_next = _head;_head->_prev = _head;}//有参构造函数(初始化n个结点)list(size_t n, const T& val = T()){_head = new Node();_head->_next = _head;_head->_prev = _head;for (size_t i = 0; i < n; i++){push_back(val);}}//迭代器构造函数template<class InputIterator>list(InputIterator first, InputIterator last){_head = new Node();_head->_next = _head;_head->_prev = _head;while (first != last){push_back(*first);first++;}}//清空链表数据void clear(){/*iterator it = begin();while (it != end()){iterator del = it++;delete del._node;}//更新哨兵位_head->_next = _head;_head->_prev = _head;*/iterator it = begin();while (it != end()){erase(it++);}}//析构函数~list(){clear();delete _head;_head = nullptr;}//拷贝构造/*list(const list<T>& lt){_head = new Node();_head->_next = _head;_head->_prev = _head;for (auto e : lt){push_back(e);}}*///拷贝构造pluslist(const list<T>& lt){_head = new Node();_head->_next = _head;_head->_prev = _head;list<T> tmp(lt.begin(), lt.end());swap(_head, tmp._head);}//赋值/*list<T>& operator=(list<T> lt){if (this != <){clear();for (auto e : lt){push_back(e);}}return *this;}*///赋值pluslist<T>& operator=(list<T> lt){swap(_head, lt._head);return *this;}//pos前插入void insert(iterator pos, const T& x){//prv new cur/pos nextNode* cur = pos._node;Node* prv = cur->_prev;Node* newnode = new Node(x);//prv连接newprv->_next = newnode;newnode->_prev = prv;//new连接curnewnode->_next = cur;cur->_prev = newnode;}//删除pos处数据iterator erase(iterator pos){assert(pos != end());//prv cur/pos nextNode* cur = pos._node;Node* prv = cur->_prev;Node* next = cur->_next;delete cur;//prv连接nextprv->_next = next;next->_prev = prv;return iterator(next);}// 尾插void push_back(const T& x){/*//创建新结点Node* newnode = new Node(x);//定位尾结点Node* tail = _head->_prev;//tail连接newtail->_next = newnode;newnode->_prev = tail;//new连接headnewnode->_next = _head;_head->_prev = newnode;*/insert(end(), x);}// 头插 void push_front(const T& x){insert(begin(), x);}//尾删void pop_back(){erase(--end());}//头删void pop_front(){erase(begin());}private:Node* _head;};/////打印链表(使用const迭代器)void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";it++;}cout << endl;}// 无参构造 尾插 迭代器 void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);//正向迭代器list<int>::iterator it = lt.begin();while (it != lt.end()){*it *= 2;cout << *it << " ";it++;}cout << endl;//反向迭代器list<int>::riterator rit = lt.rbegin();while (rit != lt.rend()){*rit *= 2;cout << *rit << " ";rit++;}cout << endl;}//打印函数void test_list2(){list<int> lt;lt.push_back(2);lt.push_back(4);lt.push_back(6);lt.push_back(8);print_list(lt);}//创建日期类 测试成员访问运算符struct Date{int _year;int _month;int _day;Date(int year = 1, int month = 1, int day = 1): _year(year), _month(month), _day(day){}};void test_list3(){list<Date> lt;lt.push_back(Date(2023, 7, 21));lt.push_back(Date(2023, 7, 22));lt.push_back(Date(2023, 7, 23));list<Date>::iterator it = lt.begin();while (it != lt.end()){cout << it->_year << "-" << it->_month << "-" << it->_day << endl;it++;}cout << endl;}//拷贝构造函数void test_list4(){list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);list<int> lt2(lt1);for (auto e : lt2)cout << e << " ";}//清空函数void test_list5(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);print_list(lt);lt.clear();print_list(lt);}
}
2.4 vector.h
#pragma once
#include <assert.h>
#include <iostream>
#include "riterator.h"
using namespace std;
namespace apex
{template<class T>//一、vector类class vector{public://迭代器 typedef T* iterator;typedef const T* const_iterator;typedef __reverse_iterator<iterator, T&, T*> riterator;typedef __reverse_iterator<const_iterator, const T&, const T*> const_riterator;//正向迭代器函数iterator begin(){return _start;}const_iterator begin() const{return _start;}iterator end(){return _finish;}const_iterator end() const{return _finish;}//正向迭代器函数riterator rbegin(){return riterator(end());}const_riterator rbegin() const{return const_riterator(end());}riterator rend(){return riterator(begin());}const_riterator rend() const{return const_riterator(begin());}// 无参构造vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}// 有参构造//T():匿名对象vector(size_t n, const T& val = T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(n);for (size_t i = 0; i < n; ++i){push_back(val);}}// 迭代器构造//为什么不直接用iterator?//iterator只能使用vector //再定义一个模板:可以使用多种类型的迭代器template <class InputIterator>vector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){while (first != last){push_back(*first);++first;}}//拷贝构造传统写法1.0/*vector(const vector<T>& v){size_t sz = v.size();_start = new T[sz];//0.size capacity都行:拷贝内容即可 有可能不对拷贝对象操作//1.拷贝的空间是size 对拷贝对象操作 -- 扩容//2.拷贝的空间是capacity 不对拷贝对象操作 -- 空间浪费//memcpy(_start, v._start, sizeof(T) * sz); ==》无法解决vector<vector<int>>//以及下方reserve的问题 使用赋值 -- 自定义类型调用它们各自的赋值重载 -- 实现二层深拷贝for (size_t i = 0; i < sz; ++i){_start[i] = v._start[i];}_finish = _start + sz;_end_of_storage = _start + sz;}*///拷贝构造传统写法1.1/*vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(v.size()); //reserve开空间for (const auto& e : v) //const:防止v被改变{push_back(e);}}*/// 拷贝构造高级写法void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);}vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){vector<T> tmp(v.begin(), v.end());//迭代器 -- push_back -- reserve -- 二层深拷贝swap(tmp);}// 赋值重载vector<T>& operator=(vector<T> v){swap(v);return *this;}//析构函数~vector(){delete[] _start;_start = _finish = _end_of_storage = nullptr;}//获取capacity的大小(vector没有此变量)size_t capacity() const{return _end_of_storage - _start;}//获取size的大小(vector没有此变量)size_t size() const{return _finish - _start;}// [] 重载T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos) const{assert(pos < size());return _start[pos];}//扩容 -- 涉及到开新空间 -- 拷贝内容 -- 拷贝的可能是自定义类型void reserve(size_t n){if (n > capacity()){size_t sz = size();T* tmp = new T[n];if (_start != nullptr){//memcpy(tmp, _start, sizeof(T) * sz);for (size_t i = 0; i < sz; ++i){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}//扩容 + 初始化void resize(size_t n, const T& val = T()){//1. n > capacity -- 扩容 + 初始化if (n > capacity()){reserve(n);}//2. size < n < capacity -- 初始化if (n > size()){while (_finish < _start + n){*_finish = val;++_finish; //finish移到新的"end"==>_start + n}}//3. n < size -- 删除数据else{_finish = _start + n; //直接更新finish即可}}//增加数据 (可修改)//const:匿名对象 隐式转换(临时变量【具有常性】) 左值 + 右值 void push_back(const T& x){/*if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;*/insert(end(), x);}// pop_backvoid pop_back(){assert(_finish > _start);--_finish;}// insertiterator insert(iterator pos, const T& x){assert(pos >= _start && pos <= _finish);if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2); //扩容后 空间地址更新 pos仍指向原空间pos处//走下面的while时 访问pos --> errorpos = _start + len; //为防止pos失效 连带更新pos}// 挪动数据iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}// eraseiterator erase(iterator pos){assert(pos >= _start);assert(pos < _finish);iterator begin = pos + 1;while (begin < _finish){*(begin - 1) = *begin;++begin;}--_finish;if (size() < capacity() / 2){// 缩容 -- 以时间换空间//缩容--空间更新--pos失效--更新pos--只能解决形参作用域内的pos失效//当再次erase--访问pos :error}return pos; // 删除数据之后 返回pos --> pos指向被删除的值 // 目标值被删除后 数据前移 pos指向空间不变 只不过pos指向的值是 目标值后的值}//frontT& front(){assert(size() > 0);return *_start;}//backT& back(){assert(size() > 0);return *(_finish - 1);}private:iterator _start;iterator _finish;iterator _end_of_storage;};
//二、命名空间内的函数// 增 删 [] size() 迭代器 范围forvoid test_vector1(){vector<int> v;//push_backv.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);// [] size()for (size_t i = 0; i < v.size(); ++i){cout << v[i] << " ";}cout << endl;//正向迭代器vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;//反向迭代器vector<int>::riterator rit = v.rbegin();while (rit != v.rend()){cout << *rit << " ";++rit;}cout << endl;//pop_backv.pop_back();v.pop_back();//范围forfor (auto e : v){cout << e << " ";}cout << endl;}// 迭代器失效问题(1) -- insert(野指针问题)void test_vector2(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);for (auto e : v){cout << e << " ";}cout << endl;auto p = find(v.begin(), v.end(), 3);if (p != v.end()){v.insert(p, 30);//在p位置插入数据后不要访问p-->p可能失效://插入需要扩容 扩容会更新空间地址 pos仍指向源空间的pos处 pos失效//即便改进了insert代码 更新了pos -->解决了insert中while循环内访问pos的问题 //但是形参改变不影响实参 在作用外pos仍失效 //为什么不使用引用?//v.insert(v.begin(), 1); -->//iterator begin()//{// return _start;//}//返回临时拷贝--具有常性--与引用可以修改的特性不匹配//那改成:const iterator& pos -->//内部无法对_start修改///** cout << *p << endl;v.insert(p, 40);*/}for (auto e : v){cout << e << " ";}cout << endl;}// erasevoid test_vector3(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (auto e : v){cout << e << " ";}cout << endl;auto p = find(v.begin(), v.end(), 3);if (p != v.end()){v.erase(p);}for (auto e : v){cout << e << " ";}cout << endl;v.erase(v.begin());for (auto e : v){cout << e << " ";}cout << endl;}// 迭代器失效问题(2) -- erase 删除所有的偶数 (迭代器位置问题)void test_vector4(){// 正常运行--lucky// 1 2 3 4 5 --> 1 3 5 -- it == end 循环结束vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);// 崩溃// 1 2 3 4 --> 1 4 -- end在4后一个 it在4后两个 it != end 循环无法结束v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);// 结果不对// 1 2 4 3 4 5 -- erase 2 --> 1 4 3 4 5 it再++ 直接跳过4v.push_back(1);v.push_back(2);v.push_back(4);v.push_back(3);v.push_back(4);v.push_back(5);auto it = v.begin();//错误/*while (it != v.end()){if (*it % 2 == 0){v.erase(it);}++it;}*///正确while (it != v.end()){if (*it % 2 == 0){it = v.erase(it); //it不在++ 而是停留在此处}else //是奇数才++{++it;}}for (auto e : v){cout << e << " ";}cout << endl;}// 迭代器失效问题(3) -- insert (扩容野指针 + 迭代器位置问题)void test_vector5(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);// 在所有偶数前插入该数2倍的值auto it = v.begin();while (it != v.end()){if (*it % 2 == 0){it = v.insert(it, *it * 2); //1.it重新赋值:插入大概率回扩容 一旦扩容 空间更新 it成为野指针// insert函数返回新的指向原位置的迭代器 it重新赋值 成功解决问题//2.插入后不再 ++ :使it停留在此处// 下面两次++是按题意 1 2 3 ——> 1 4 2 3
// --> it指向4 ++两次指向3(即进行下一次寻找)++it;++it;}else{++it;}}for (auto e : v){cout << e << " ";}cout << endl;}// 迭代器失效问题(4) -- erase (缩容野指针 + 迭代器位置问题)/*待实现*///总结:迭代器失效问题 //1.扩容导致的野指针问题//2.插入或删除导致的迭代器位置错误问题//拷贝构造 void test_vector6(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);// 1 2 3 4 5for (auto e : v){cout << e << " ";}cout << endl;//拷贝构造vector<int> v1(v);v[0] *= 10; //深拷贝// 10 2 3 4 5for (auto e : v){cout << e << " ";}cout << endl;// 1 2 3 4 5for (auto e : v1){cout << e << " ";}cout << endl;}//迭代器构造void test_vector7(){string s("hello world");vector<int> vs(s.begin(), s.end());for (auto e : vs){cout << e << " ";}cout << endl;vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);vs = v; // 赋值重载:针对两个已经存在的对象vector<int> copy = v; // 拷贝构造 ==》copy(v); //copy不存在 用一个已有的对象去初始化一个新对象vs[0] *= 10;for (auto e : vs){cout << e << " ";}cout << endl;for (auto e : v){cout << e << " ";}cout << endl;}// 有参构造void test_vector8(){//C++引入了模板 ==》内置类型也可以有构造/*int i = 0;int j = int();int k = int(10);*///正常运行vector<int> v1(10);for (auto e : v1){cout << e << " ";}cout << endl;//正常运行vector<char> v3(10, 'a');for (auto e : v3){cout << e << " ";}cout << endl;// 编译错误:参数匹配//<int> v2(10, 1);//1.vector(size_t n, const T & val = T()) ; //2.vector(InputIterator first, InputIterator last);//1.int-->u_int int-->T 匹配程度低//2.int-->T int-->T 【有解引用操作】//修正1.0:vector<int> v2(10u, 1); //第一种匹配程度变高 -- ok//修正2.0://vector(int n, const T & val = T()) ; for (auto e : v2){cout << e << " ";}cout << endl;}// resizevoid test_vector9(){vector<int> v1;v1.resize(10, 0);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2;v2.reserve(10);v2.push_back(1);v2.push_back(2);v2.push_back(3);v2.push_back(4);v2.push_back(5);v2.resize(8, 8);for (auto e : v2){cout << e << " ";}cout << endl;v2.resize(20, 20);for (auto e : v2){cout << e << " ";}cout << endl;v2.resize(3);for (auto e : v2){cout << e << " ";}cout << endl;}//vv的深拷贝天坑void test_vector10(){class Solution{public:vector<vector<int>> generate(int n){vector<vector<int>> Vv;Vv.resize(n);for (size_t i = 0; i < Vv.size(); ++i){Vv[i].resize(i + 1, 0);Vv[i].front() = Vv[i].back() = 1;}for (size_t i = 0; i < Vv.size(); ++i){for (size_t j = 0; j < Vv[i].size(); ++j){if (Vv[i][j] == 0){Vv[i][j] = Vv[i - 1][j] + Vv[i - 1][j - 1];}}}//打印查看for (size_t i = 0; i < Vv.size(); ++i){for (size_t j = 0; j < Vv[i].size(); ++j){cout << Vv[i][j] << " ";}cout << endl;}return Vv;}};vector<vector<int>> ret = Solution().generate(5);}
}
2.5test.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
#include <array>
#include <time.h>
#include <queue>
using namespace std;#include "list.h"
#include "vector.h"int main()
{apex::test_vector1();return 0;
}
3.反向迭代器的应用
1.使用要求
该容器要能够实现++、–操作,如单向链表或单向map不可使用。
2.迭代器的分类
单向迭代器forward_iterator_tag:支持++:forward_list、unordered_map、unordered_set、
双向迭代器bidirectional_iterator_tag:支持++ --:list 、map、set、
随机迭代器random_access_iterator_tag:支持++ – + -:deque、vector
只读迭代器
只写迭代器
相关文章:
list模拟实现【引入反向迭代器】
文章目录 1.适配器1.1传统意义上的适配器1.2语言里的适配器1.3理解 2.list模拟实现【注意看反向迭代器】2.1 list_frame.h2.2riterator.h2.3list.h2.4 vector.h2.5test.cpp 3.反向迭代器的应用1.使用要求2.迭代器的分类 1.适配器 1.1传统意义上的适配器 1.2语言里的适配器 容…...
【华为OD机试】字符串变换最小字符串【2023 B卷|100分】
【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述: 给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。 变换规则:交换字符串中任意两个不同位置的字符。 输入描述: 一串小写字母组成的字…...
ARTS 挑战打卡的第8天 ---volatile 关键字在MCU中的作用,四个实例讲解(Tips)
前言 (1)volatile 关键字作为嵌入式面试的常考点,很多人都不是很了解,或者说一知半解。 (2)可能有些人会说了,volatile 关键字不就是防止编译器优化的吗?有啥好详细讲解的࿱…...
第二课-一键安装SD-Stable Diffusion 教程
前言 看完这篇文章并跟着操作,就可以在本地开始 SD 绘图了。 理论上来说,这篇课程结束,想要画什么图都可以画了。 启动器介绍 SD 是开源的,可以在 github 上找到。但直接下载源码安装,非常费劲,而且因为国内外差异,就是我这样的秃头程序员也难以应对。 所以,我们改…...
Vue3 动态列 <el-table-column> 实现 formatter 的两种方法
文章目录 动态列实现动态列实现formatter第一种第二种方法 动态列实现 参考此篇文章 Vue3 动态列实现 动态列实现formatter 第一种 以此为例:传递该行的wxUserInfo字段(对象)中的nickName 假设该行 {prop: "wxUserInfo", label: …...
室温超导是什么?有哪些应用场景?
目录 一、应用场景:二、案例分析: 室温超导是指在室温下(即约 20C 至 30C)实现超导现象的材料。超导是指某些材料在低温下电阻为零的物理现象,室温超导材料是超导材料的一种。室温超导现象的发现和研究是超导领域的一个…...
Windows+VMware+Ubuntu+Anaconda+VMware Tools
Q1:Windows不支持***agent模拟器 A1:在VMware安装Ubuntu虚拟机 P1: 下载 VMware-workstation-full-15.5.6-16341506.exe 安装包(峰哥电脑软件) P2: 下载Ubuntu镜像 地址 ubuntu-18.04.6-desktop-amd64.iso P3:搭载镜…...
Xray配置文件详解
Xray配置文件详解 1.并发配置2.HTTP配置3.插件配置4.被动代理配置5.反连平台配置1.并发配置 在配置文件中可以用下面的配置改变漏洞探测的 worker 数量: parallel: 30 # 漏洞探测的 worker 数量,可以简单理解为同时有 30 个 POC 在运行这个值并非越大越好,因为高并发的情况…...
flink优化
1. 大状态调优 大状态调优:在我们的项目中,在做新老访客修复时,我们将每个mid的访问时间都存到了状态里面,在做回流用户数时,我们将每个用户的登录时间都存到了状态里面,导致了大状态问题,由于…...
docker: ERROR: Couldn‘t connect to Docker daemon at http+docker://localhost
环境: linuxt centos 7.x 如下图, 使用docker-compose时,提示错误 [explorebridge tinyproxy]$ docker-compose up ERROR: Couldnt connect to Docker daemon at httpdocker://localhost - is it running?If its at a non-standard locati…...
大模型在金融医疗、生命系统和物理仿真领域的创新应用探索
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 在当今迅速发展的科技领域,大模型技术正日益成为金融医疗、生命系统和物理仿真等领域中的重要工具。2023年6月16日,AI TIME举办的青年科学家大模型专场活动邀请了国防科技大学理学院数学…...
tensorflow / tensorflow-gpu cuda cudNN tensorRT 安装,启用显卡加速
tensorflow / tensorflow-gpu cuda cudNN tensorRT 安装,启用显卡加速 说明 Tensorflow-GPU 已被移除。请安装 tensorflow 。 tensorflow 通过 Nvidia CUDA 支持 GPU 加速操作。 自 2019 年 9月发布 的 TensorFlow2.1 以来,tensorFlow 和 tensorflow-GPU 一直是同…...
计算机视觉中的Transformer
几十年来,理论物理学家一直在努力提出一个宏大的统一理论。通过统一,指的是将被认为是完全不同的两个或多个想法结合起来,将它们的不同方面证明为同一基础现象。一个例子是在19世纪之前,电和磁被看作是无关的现象,但电…...
UVA-1601 万圣节后的早晨 题解答案代码 算法竞赛入门经典第二版
GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 以三个点的当前位置作为状态,广度优先遍历,找到终点即为最短次数。 注意: 一次可以移动多个点,但是每个点只能移动一步。在同一次中…...
nacos 403错误
403错误 2023-08-12 18:04:55,418 [main] ERROR [com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder:106] [trace,span,parent] - get data from Nacos error,dataId:gateway-server.yaml, com.alibaba.nacos.api.exception.NacosException: <html><body&…...
Python遥感图像处理应用篇(三十四):GDAL+Scikit-image+GLCM计算遥感图像纹理特征
1.运行环境 GDAL 3.4.2,Scikit-image最新版本0.19.3,numpy1.21.5 GDAL主要用于实现图像的读取和保存,Scikit-image和numpy对图像进行各种计算处理。 在调试好之前,由于numpy版本(1.16.6)低的问题,运行提示如下错误,更新为1.21.5版本之后就可以正常运行了,在此记录一…...
solr迁移到另一个solr中(docker单机)
背景介绍 solr数据迁移,或者版本升级,需要用到迁移,此处记录一下迁移方法以及过程中遇到的问题。我这边使用的是docker环境,非docker部署的应该也是一样的。 solr部署教程 准备工作 ● solrA 版本: 8.11.2 (已有so…...
谁能讲清楚Spark之Spark系统架构
### 整体架构概述 Spark与Hadoop MapReduce的结构类似,Spark也采用Master-Worker结构。如果一个Spark集群由4个节点组成,即1个Master节点和3个Worker节点,那么在部署Standalone版本后,Spark部署的系统架构图如图2.1所示。简单来说,Master节点负责管理应用和任务,…...
力扣:59. 螺旋矩阵 II(Python3)
题目: 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 来源:力扣(LeetCode) 链接:力扣(LeetCode)官网 - 全…...
【electron】electron项目创建的方式:
文章目录 【1】npm init quick-start/electron(推荐)【2】 克隆仓库,快速启动【3】 通过脚手架搭建项目【4】 手动创建项目 【Electron官网】https://www.electronjs.org/zh/docs/latest/api/app 【1】npm init quick-start/electron…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...
Git 命令全流程总结
以下是从初始化到版本控制、查看记录、撤回操作的 Git 命令全流程总结,按操作场景分类整理: 一、初始化与基础操作 操作命令初始化仓库git init添加所有文件到暂存区git add .提交到本地仓库git commit -m "提交描述"首次提交需配置身份git c…...
