06 STL中的vector类和模拟实现
文章目录
- 一、vector的介绍
- 二、常用接口
- 2.1. 构造函数
- 默认构造
- 半缺省构造
- 拷贝构造
- 迭代器构造
- 2.2. 元素访问方式
- [ ]下标访问
- 迭代器和范围for访问
- 2.3. 空间增长函数
- size()和capacity()
- reserve()和resize()
- capacity增容规则
- 2.4. 增删查改的接口
- push_back和pop_back
- insert和erase
- find函数
- swap
- 2.5. 迭代器
- begin和end
- rbegin和rend
- 三、vector迭代器失效的问题
- 3.1. 迭代器失效解决方法
- 四、vector模拟实现
- 4.1. 构造函数
- 默认构造和半缺省构造
- 迭代器构造
- 拷贝构造函数
- 析构函数
- 赋值运算符重载函数
- 4.2. 迭代器
- begin()和end()
- 4.3. 容量函数
- size()和capacity()
- reserve
- resize
- empty
- 4.4. 增删查改
- push_back
- pop_back
- insert
- erase
- swap
- 4.5. 元素访问函数
- operator[ ]
- 附录
一、vector的介绍
1、vector是表示可变大小数组的序列容器。
2、vector就像数组一样,也采用的连续空间来存储元素,这也意味着可以采用下标对vector的元素进行访问。
3、vector与普通数组不同的是,vector的大小是可以动态改变的。
4、当vector需要重新分配大小时,其做法是,分配一个新的数组,然后将全部元素移到这个数组当中,并释放原来的数组空间。
5、vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因此存储空间比实际需要的存储空间一般更大。不同的库采用不同的策略权衡空间的使用和重新分配,以至于在末尾插入一个元素的时候是在常数的时间复杂度完成的。
6、由于vector采用连续的空间来存储元素,与其他动态序列容器相比,vector在访问元素的时候更加高效,在其末尾添加和删除元素相对高效,而对于不在其末尾进行的删除和插入操作效率则相对较低。
值得注意的是,vector不管在实现方式上还是在用法上和string都非常像,不过它们之间还是有区别的,string
类是一个保存字符的动态数组,由于其中有一个接口c_str
,可以将其转化成c语言的字符串,要以\0
结尾,所以string
类最后会有一个\0
。
vector<T>
是一个保存T
类型的动态数组,vector<char>
也是保存字符的动态数组,但是,不会以\0
结尾,不保存\0
。
它们两个的本质都是一个顺序表。头文件iostream中并不包含vector,因此使用时要加头文件<vector>
二、常用接口
2.1. 构造函数
默认构造
构造一个某类型的空容器:
explicit vector (const allocator_type& alloc = allocator_type());
缺省参数allocator,它是用于指定要使用的空间配置器的,STL提供的默认的空间配置器,我们基本不用管这个参数,除非是我们自己实现了一个空间配置器,然后希望使用我们自己写的空间配置器。
vector<int> v; //构造int类型的空容器
半缺省构造
构造一个含有n个val(val默认为0)的某类型容器:
explicit vector (size_type n, const value_type& val = value_type(),const allocator_type& alloc = allocator_type());
vector<int> v2(10, 1); //构造含有10个1的int类型容器
拷贝构造
vector (const vector& x);
迭代器构造
使用迭代器拷贝构造某一段内容:
template <class InputIterator>vector (InputIterator first, InputIterator last,const allocator_type& alloc = allocator_type());
该方式也可用于拷贝其他容器的某一段内容,这是因为vector的成员函数是模板函数,只要迭代器解引用后和vector实例化后的类型是一致的就可以进行传参:
string s("hello world");
vector<char> v5(s.begin(), s.end()); //拷贝构造string对象的某一段内容
2.2. 元素访问方式
[ ]下标访问
vector当中实现了 [ ] 操作符的重载,因此我们也可以通过“下标+[ ]”的方式对容器当中的元素进行访问。
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v(10, 1);//使用"[]下标”的方式遍历容器for (size_t i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;return 0;
}
迭代器和范围for访问
编译器会自动将范围for替换为迭代器的形式,vector是支持迭代器的,所以我们还可以用范围for对vector容器进行遍历:
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v(10, 1);//范围forfor (const auto& e : v){cout << e << " ";}cout << endl;//迭代器vector<int>::iterator it = v.begin();while (it != v.end()) {cout << *it << " ";it++;}cout << endl;return 0;
}
范围for的本质是将v的内容取出来拷贝给e,如果vector是内置类型的消耗很小,但如果其内容是string类型的会发生深拷贝,产生巨大消耗,因此需要引用传参。
2.3. 空间增长函数
size()和capacity()
size()函数获取当前容器中的有效元素个数,通过capacity()函数获取当前容器的最大容量。
reserve()和resize()
void reserve (size_type n);
void resize (size_type n, value_type val = value_type());
通过reserse()函数改变容器的最大容量,resize()函数改变容器中的有效元素个数。
reserve规则:
1、当所给值大于容器当前的capacity时,将capacity扩大到该值。
2、当所给值小于容器当前的capacity时,什么也不做。
resize规则:
1、当所给值大于容器当前的size时,将size扩大到该值,扩大的元素为第二个所给值,若未给出,则默认为0。
2、当所给值小于容器当前的size时,将size缩小到该值。
capacity增容规则
#include <iostream>
#include <vector>
int main()
{size_t sz;std::vector<int> foo;sz = foo.capacity();std::cout << "making foo grow:\n";for (int i = 0; i < 100; ++i) {foo.push_back(i);if (sz != foo.capacity()) {sz = foo.capacity();std::cout << "capacity changed: " << sz << '\n';}}
}
capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。
这是因为vs是PJ版本STL,g++是SGI版本STL。
C++标准委员会只是规定了,一个容器的名称、应该提供哪些接口,并没有规定接口的底层的实现方法。因此,不同的编译器提供的接口底层实现方法有可能是不同的,这是实现者的自由。
至于为什么是扩容1.5倍或2倍,则是因为设计者的考虑。扩容的倍数越高,扩容的频率就越低,同时有可能浪费的空间容量就越大。 如果确定要多少空间,我们可以通过reserve/resize提前将空间给开辟好
2.4. 增删查改的接口
push_back和pop_back
容器的尾插和尾删,值得注意的是,vector并没有提供头插和头删,因为头插和头删的效率比较低(要向后移动元素),不过头插和头删可以采用inset和erase实现。
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;v.push_back(1); //尾插元素1v.push_back(2); //尾插元素2v.push_back(3); //尾插元素3v.push_back(4); //尾插元素4v.pop_back(); //尾删元素v.pop_back(); //尾删元素v.pop_back(); //尾删元素v.pop_back(); //尾删元素return 0;
}
insert和erase
//在pos位置插入val,返回val的位置
iterator insert (iterator position, const value_type& val);//在pos位置插入n个val
void insert (iterator position, size_type n, const value_type& val);//在pos位置插入一段区间
template <class InputIterator>void insert (iterator position, InputIterator first, InputIterator last);
//删除pos位置的元素,返回值是pos位置的下一个元素的迭代器
iterator erase (iterator position);
//删除一段区间,返回值是这段区间的下一个元素的迭代器
iterator erase (iterator first, iterator last);
find函数
template <class InputIterator, class T>InputIterator find (InputIterator first, InputIterator last, const T& val);
find函数共三个参数,前两个参数确定一个迭代器区间(左闭右开),第三个参数确定所要寻找的值。
find函数在所给迭代器区间寻找第一个匹配的元素,并返回它的迭代器,若未找到,则返回所给的第二个参数。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int>::iterator pos = find(v.begin(), v.end(), 2); //获取值为2的元素的迭代器v.insert(pos, 10); //在2的位置插入10pos = find(v.begin(), v.end(), 3); //获取值为3的元素的迭代器v.erase(pos); //删除3return 0;
}
swap
swap函数可以交换两个容器的数据空间,实现两个容器的交换。
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v1(10, 1);vector<int> v2(10, 2);v1.swap(v2); //交换v1,v2的数据空间return 0;
}
2.5. 迭代器
begin和end
begin()
函数返回容器中第一个元素的正向迭代器,end()
函数返回容器中最后一个元素的后一个位置的正向迭代器。
rbegin和rend
rbegin()
函数返回容器中最后一个元素的反向迭代器,rend()
函数返回容器中第一个元素的前一个位置的反向迭代器。
三、vector迭代器失效的问题
实例一:
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;for (size_t i = 1; i <= 6; i++){v.push_back(i);}vector<int>::iterator it = v.begin();while (it != v.end()){if (*it % 2 == 0) //删除容器当中的全部偶数{v.erase(it);}it++;}return 0;
}
迭代器访问到了不属于容器的内存空间,导致程序崩溃:
不仅如此,而且在迭代器遍历容器中的元素进行判断时,并没有对1、3、5元素进行判断。
除此之外,当原来的空间被释放,原来的迭代器就指向了一块已经被释放的空间。
实例二:
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v(10,0);v[1] = 10;auto pos = find(v.begin(), v.end(),10);v.insert(pos, 0);v.erase(pos); return 0;
}
3.1. 迭代器失效解决方法
每次使用前,对迭代器进行重新赋值就可以解决这个问题。
对于实例一,我们可以接收erase函数的返回值(erase函数返回删除元素的后一个元素的新位置)。并且控制代码的逻辑:当元素被删除后继续判断该位置的元素(因为该位置的元素已经更新,需要再次判断)。
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v;for (size_t i = 1; i <= 6; i++){v.push_back(i);}vector<int>::iterator it = v.begin();while (it != v.end()){if (*it % 2 == 0) //删除容器当中的全部偶数{it = v.erase(it); //删除后获取下一个元素的迭代器}else{it++; //是奇数则it++}}return 0;
}
对于实例二,可以在删除之前再次重新查找一遍。
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v(10,0);v[1] = 10;auto pos = find(v.begin(), v.end(),10);v.insert(pos, 0);pos = find(v.begin(), v.end(), 10); //获取值为2的元素的迭代器v.erase(pos); return 0;
}
四、vector模拟实现
vector中有三个成员变量:
private:iterator _start; // 指向数据块的开始iterator _finish; // 指向有效数据的尾iterator _endofStorage; // 指向存储容量的尾
在vector当中有三个成员变量_start、_finish、_endofstorage。
_start指向容器的头,_finish指向容器当中有效数据的尾,_endofstorage指向整个容器的尾。
4.1. 构造函数
默认构造和半缺省构造
vector(int size=0, T val = T()): _start(nullptr), _finish(nullptr), _endofStorage(nullptr)
{assert(size >= 0);if (size>0){_start = new T[size];if (_start){for (size_t i = 0; i < size; ++i)_start[i] = val;}_finish = _start + size;_endofStorage = _start + size;}
}
迭代器构造
template<class InputIterator> //模板函数
vector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _endofStorage(nullptr)
{//将迭代器区间在[first,last)的数据一个个尾插到容器当中while (first != last){push_back(*first);first++;}
}
拷贝构造函数
拷贝构造函数的传统写法:
//现代写法
vector(const vector<T>& v):_start(nullptr), _finish(nullptr), _endofStorage(nullptr)
{reserve(v.capacity()); //开辟与v相同的空间for (auto e : v) //将容器v当中的数据一个个尾插过来{push_back(e);}
}//也可以采用这种写法
//vector(const vector<T>& v)
//:_start(nullptr)
//, _finish(nullptr)
//, _endofStorage(nullptr)
//{//拷贝构造
// _start = new T[v.capacity()];
// size_t size = v.size();
// if (_start)
// {
// for (size_t i = 0; i < size; ++i)//不能使用memcpy
// _start[i] = v._start[i];
// }
// _endofStorage = _start + v.capacity();
// _finish = _start + v.size();
//}
注意这里不能使用memcpy来拷贝数据,因为memcpy是浅拷贝,当vector中的类型为string等数据时,则需要使用深拷贝来完成(这里就是string自己的=赋值运算符重载)。
析构函数
~vector() {if (_start)delete[]_start;_start = _finish = _endofStorage = nullptr;
}
赋值运算符重载函数
vector<T>& operator=(vector<T> v) //拷贝构造一个形参
{swap(v); //交换这两个对象return *this; //支持连续赋值
}//也可以采用这种写法
//vector<T>& operator=(const vector<T>& v)
//{
// if (this != &v) //防止自己给自己赋值
// {
// delete[] _start; //释放原来的空间
// _start = new T[v.capacity()]; //开辟一块和容器v大小相同的空间
// for (size_t i = 0; i < v.size(); i++) //将容器v当中的数据一个个拷贝过来
// {
// _start[i] = v[i];
// }
// _finish = _start + v.size(); //容器有效数据的尾
// _endofStorage = _start + v.capacity(); //整个容器的尾
// }
// return *this; //支持连续赋值
//}
4.2. 迭代器
// Vector的迭代器是一个原生指针
typedef T* iterator;
typedef const T* const_iterator;
begin()和end()
iterator begin()
{return _start; //返回容器的首地址
}
iterator end()
{return _finish; //返回容器当中有效数据的下一个数据的地址
}
const_iterator begin()const
{return _start; //返回容器的首地址
}
const_iterator end()const
{return _finish; //返回容器当中有效数据的下一个数据的地址
}
4.3. 容量函数
size()和capacity()
size_t size()const
{return _finish - _start; //返回容器当中有效数据的个数
}
size_t capacity()const
{return _endofStorage - _start; //返回当前容器的最大容量
}
reserve
void reserve(size_t n)
{if (n > capacity()) //判断是否需要进行操作{size_t sz = size(); //为了防止_finish失效,先记录当前容器当中有效数据的个数T* tmp = new T[n]; //开辟空间if (_start) //判断是否为空容器{for (size_t i = 0; i < sz; i++) //将容器当中的数据一个个拷贝到tmp当中{tmp[i] = _start[i];}delete[] _start; //将容器本身存储数据的空间释放}_start = tmp; //将tmp所维护的数据交给_start进行维护_finish = _start + sz; //容器有效数据的尾_endofStorage = _start + n; //容器的尾}
}
resize
void resize(size_t n, const T& val = T())
{if (n < size()) //当n小于当前的size时{_finish = _start + n; //将size缩小到n}else //当n大于当前的size时{if (n > capacity()) //判断是否需要增容{reserve(n);}while (_finish < _start + n) //将size扩大到n{*_finish = val;_finish++;}}
}
empty
bool empty()const
{return _start == _finish;
}
4.4. 增删查改
push_back
//尾插数据
void push_back(const T& x)
{if (_finish == _endofstorage) //判断是否需要增容{size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity(); //将容量扩大为原来的两倍reserve(newcapacity); //增容}*_finish = x; //尾插数据_finish++; //_finish指针后移
}
pop_back
//尾删数据
void pop_back()
{assert(!empty()); //容器为空则断言_finish--; //_finish指针前移
}
insert
//插入
iterator insert(iterator pos, const T& x) {if (_finish == _endofStorage) {size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}size_t inpos = pos - _start;//保存一份相对位置,防止迭代器失效pos = _start + inpos;iterator last = _finish;while (last != pos){//往后挪动*last = *(last - 1);last--;}*pos = x;_finish++;return pos;//返回pos指向新插入元素的位置
}
erase
//删除
iterator erase(iterator pos) {assert(pos >= _start && pos < _finish);iterator temp_pos = pos;//保存原来pos的位置while (pos < _finish - 1)//将pos后面的元素往前移{*pos = *(pos + 1);pos++;}_finish--;return temp_pos;//返回原来的位置
}
swap
swap函数用于交换两个容器的数据,我们可以直接调用库当中的swap函数将两个容器当中的各个成员变量进行交换即可。
//交换两个容器的数据
void swap(vector<T>& v)
{//交换容器当中的各个成员变量std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofStorage, v._endofStorage);
}
4.5. 元素访问函数
operator[ ]
T& operator[](size_t i)
{assert(i < size()); //检测下标的合法性return _start[i]; //返回对应数据
}
const T& operator[](size_t i)const
{assert(i < size()); //检测下标的合法性return _start[i]; //返回对应数据
}
附录
namespace hjl
{template<class T>class vector{public:// Vector的迭代器是一个原生指针typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin()const{return _start;}const_iterator end()const{return _finish;}//构造和半缺省构造vector(int size=0, T val = T()): _start(nullptr), _finish(nullptr), _endofStorage(nullptr){assert(size >= 0);if (size>0){_start = new T[size];if (_start){for (size_t i = 0; i < size; ++i)_start[i] = val;}_finish = _start + size;_endofStorage = _start + size;}}//迭代器构造template<class InputIterator> //模板函数vector(InputIterator first, InputIterator last):_start(nullptr), _finish(nullptr), _endofStorage(nullptr){//将迭代器区间在[first,last)的数据一个个尾插到容器当中while (first != last){push_back(*first);first++;}}void swap(vector<T>& x){std::swap(_start, x._start);std::swap(_finish, x._finish);std::swap(_endofStorage, x._endofStorage);}//拷贝构造vector(const vector<T>& v):_start(nullptr),_finish(nullptr),_endofStorage(nullptr){_start = new T[v.capacity()];size_t size = v.size();if (_start){for (size_t i = 0; i < size; ++i)_start[i] = v._start[i];}_endofStorage = _start+v.capacity();_finish = _start + v.size();}//重载=vector<T>& operator=(vector<T> v) //编译器接收右值的时候自动调用其拷贝构造函数{swap(v); //交换这两个对象return *this; //支持连续赋值}~vector() {if (_start)delete[]_start;_start = _finish = _endofStorage = nullptr;}// capacitysize_t size() const {return _finish - _start;}size_t capacity() const {return _endofStorage - _start;}bool empty() const {return _start == _finish;}//重载[]T& operator[](size_t i){assert(i < size());return _start[i];}void reserve(size_t n) {if (n > capacity()) {size_t oldSize = size();T* tmp = new T[n];if (_start){for (size_t i = 0; i < oldSize; ++i)tmp[i] = _start[i];}delete[] _start;_start = tmp;_finish = _start + oldSize;_endofStorage = _start + n;}}void resize(size_t n,T val=T()) {//调用默认匿名对象的构造函数if (n < size()){_finish = _start + n;}else {if (n > capacity()) {reserve(n);//n比capacity大时先增容}//end ifwhile (_finish < _start + n) {*_finish = val;_finish++;}//end while}//end else}//尾插void push_back(const T& x) {if (_finish == _endofStorage) {size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}*_finish = x;_finish++;}//尾删void pop_back() {assert(!empty());_finish--;}//插入iterator insert(iterator pos, const T& x) {if (_finish == _endofStorage) {size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}size_t inpos = pos - _start;//保存一份相对位置,防止迭代器失效pos = _start + inpos;iterator last = _finish;while (last != pos){//往后挪动*last = *(last - 1);last--;}*pos = x;_finish++;return pos;//返回pos指向新插入元素的位置}//删除iterator erase(iterator pos) {assert(pos >= _start && pos < _finish);iterator temp_pos = pos;while (pos < _finish - 1)//将pos后面的元素往前移{*pos = *(pos + 1);pos++;}_finish--;return temp_pos;//返回原来的位置}private:iterator _start; // 指向数据块的开始iterator _finish; // 指向有效数据的尾iterator _endofStorage; // 指向存储容量的尾};}
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- [04] 数据操作+数据预处理
[04] 数据操作数据预处理 访问元素 一个元素:[1,2]:第一行,第二列; 一行:[1, :]:第一行所有元素; 一列:[:, 1]:第一列所有元素; 子区域:[1:3, 1:]…...
2024/5/1 21:31:42 - 机器学习——逻辑回归
逻辑回归测试笔记 1、正则化越弱,模型参数越大,模型越复杂。(对) 2、逻辑回归的损失函数与极大似然估计具有等价性。(对) 3、正则化是通过惩罚模型的参数来实现的,即惩罚大的权重值 4、skle…...
2024/4/18 15:40:51 - 力扣:136. 只出现一次的数字
1、根据两个相同数字异或结果为0,任何数与0异或结果不变的原理,所以可以将整个数组中的数全部异或起来,最终的结果就是只出现一次的数字。 class Solution { public:int singleNumber(vector<int>& nums) {int thesizenums.size()…...
2024/4/20 2:32:23 - 主機名稱控制者: DNS 伺服器
http://linux.vbird.org/linux_server/0350dns.php#Lame_server第十九章、主機名稱控制者: DNS伺服器切換解析度為 800x600最近更新日期:2011/08/05我們都知道,在『記憶』的角色上,人腦總是不如電腦的,而人們對文字的印象又比數字高。因此,想要使用純粹的 TCP/IP 來上網,…...
2024/4/5 5:37:14 - networkx节点2D网格,Python
此种类型2D网格图,类似于棋盘等。 import networkx as nx import matplotlib.pyplot as pltdef my_graph():G nx.grid_2d_graph(4, 4)pos nx.spring_layout(G, iterations100)# nrows2,ncols2,index1plt.subplot(2, 2, 1)nx.draw(G, pos, …...
2024/4/14 20:56:04 - uniapp -- (1)
一、环境部署 1、HBuilderX hbuilderX官网 2、模拟器 夜神模拟器官网 夜神模拟器 安卓模拟器 比较占用资源 需要显卡、内存、CPU配置较高。 二、uniapp介绍 uni-app 适合中小公司 能够编译称为多家小程序和APP的一套解决方案多家小程序 :百度、字节、快应用。。…...
2024/4/19 8:12:09 - C++实现基于vector的矩阵乘法
代码 #include <iostream> #include <vector> using namespace std;int main() {int m;int n;cin>>m>>n;vector<vector<int>> matrix_a(m);vector<vector<int>> matrix_b(n);int input;for (int i 0; i < m; i) {for (in…...
2024/4/14 20:55:49 - 用户注册功能-java实现
用户注册功能-java实现 实现思路 暂定结构图 暂定 /*** ClassName Register* Description TODO* Author 18752* Date 2021/11/6 19:47* Version 1.0*/public class Register {private String User_name;private String Password;private String Mail;public Register() {}pub…...
2024/4/25 6:23:44 - 浅谈Spring Security-Ldap认证配置
最近在项目中使用公司的LDAP做身份认证,积累了一些经验,与大家分享一下。首选报告一下我们项目的概况,我们的项目是用java开发的,基于 spring 的web应用。主要相关软件或库的版本为:java:1.6,maven:3.0.4,tomcat:7,spring framework:3.2.2.RELEASE,spring securit…...
2024/4/18 13:49:49 - Kafka2.7.X源码阅读环境搭建
文章目录1 准备2 构建kafka 是个好东西, 阅读源码却容易在搭建环境时就放弃… 因为实在是太多坑了. 这里记录下较高版本 2.7.1 的搭建过程.注意: 笔者 是在IDEA 中构建的; 而且低版本的构建过程可能有所区别1 准备 JDK 源码包 gradle 这些不用说了 2 构建 在目录根目录 gra…...
2024/4/14 20:55:49 - osgearth绘制线
一、代码 #include <osgViewer/Viewer> #include <osg/Math> #include <osgDB/ReadFile> #include <osg/NodeCallback> #include <osg/MatrixTransform> #include<osg/PositionAttitudeTransform> //键盘事件 #include<osgViewer/…...
2024/4/14 20:55:24 - 蓝桥杯——单片机学习(学习自检——数码管)
代码 //seg.c #include "sys.h"u8 code Nixie[] {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; //共阳数码管码字 u8 NixieBuff[] {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; //数码管显示缓冲区,初值0xff确…...
2024/4/14 20:55:44 - 21天养成好习惯第一期-14
...
2024/4/20 7:04:49 - 《人月神话》读书笔记(十)
第十一章 未雨绸缪 开发人员交付的是用户满意度,而不仅仅是有形的产品。用户的实际需要和用户感觉会随着程序的构建、测试和使用而变化。 项目目标上的一些变化无可避免,事先为它们做准备总比假设它们不会出现要好很多。不但目标上的变化不可避免&…...
2024/4/7 3:10:52 - 第一阶段 C语言基础与入门8
字符转换: 自动类型转换: 1.非赋值运算的类型转换: 数据类型的自动转换需遵循的规则见图。为保证运算精度不低,可采用以下方法: 水平方向的转换:所有char类型和short型自动地转换成int型,所有…...
2024/4/20 16:42:25 - arm平台aarch64 pip安装pytorch
比如你要安装torch1.7.1的版本,你执行下面这行命令 pip3 install torch1.7.1 torchvision0.8.2 torchaudio0.7.2 -f https://torch.kmtea.eu/whl/stable-cn.html...
2024/4/18 14:57:12 - 《程序员的自我修养》第2章---编译和链接
第2章 编译和链接 2.1 被隐藏了的过程: 一个“编译”过程可以分为4个步骤: 预处理(Prepressing)编译(Compilation)汇编(Assembly)链接(Linking) 实际上gcc…...
2024/4/14 20:55:49 - 【Thread】线程的通信(五)
1. 生产者和消费者问题 生产者和消费者问题: 仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品消费;如果仓库中没有产品,则生产者将产品放入仓库中。否则,停止生产并等待&…...
2024/4/7 3:10:46 - BILIBILI 高并发实时弹幕系统那些事(项目开源、架构演变)
B 站建立开源工作组:ijkplayer 等多个项目开源 SegmentFault 兄弟 + 基友单位弹幕视频网 Bilibili(B 站)近日在GitHub 网站上建立了开源工作组(BOSTF)(此处 1024 赞),用以分享与维护自己的开源项目,其中包括 DanmakuFlameMaster(燃烧吧!烈焰弹幕使)与 ijkplayer。前…...
2024/4/14 20:56:20 - Python入门初学二、Python安装与环境配置
兄弟们,既然要学python,那么这些软件是需要先安装一下的。 Python 安装使用 Python是运行的环境,必不可少,如果你是Linux系统的话,不用安装,自带了Python。 首先我们打开浏览器搜索Python,选择…...
2024/4/18 14:57:12
最新文章
- 搭建企业级DNS服务器真实案例精讲
搭建企业级DNS服务器真实案例精讲 1----3-2-1.1.搭建DNS服务服务器为公司的多个域名提供解析.M 2----3-2-1.2格建DNS服务服务器为公司的客不域名提供解析补 3----3-2-1.3.格建DNS服务服务器为公司的多个域名提供解析扣 4----3-2-1.4.搭建DNS服务服务器为公司的多个域名提供解析…...
2024/5/1 23:42:06 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 分发饼干(C++ 贪心)
目录 题目需求 贪心算法思想 什么是贪心 贪心算法的使用 贪心算法的优缺点 代码实现 后言 题目需求 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i]&…...
2024/4/30 5:52:03 - Mybatis--TypeHandler使用手册
TypeHandler使用手册 场景:想保存user时 teacher自动转String ,不想每次保存都要手动去转String;从DB查询出来时,也要自动帮我们转换成Java对象 Teacher Data public class User {private Integer id;private String name;priva…...
2024/5/1 14:21:06 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/1 17:30:59 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/30 18:14:14 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/4/30 18:21:48 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/25 18:39:16 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/27 23:24:42 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/4/30 9:43:22 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57