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

vector(沉淀)

文章目录

  • 1.vector的介绍及使用(顺序表)
    • 1.1 vector的介绍[vector参考文献](https://legacy.cplusplus.com/reference/)
      • 三种遍历方式
    • 1.2 vector的使用
      • Member functions
        • (1) (constructor) std::vector::vector[构造](https://legacy.cplusplus.com/reference/vector/vector/vector/)
      • Iterators(迭代器):
        • (1)正向迭代器std::vector::begin
        • (2)正向迭代器std::vector::end
        • (3)反向向迭代器std::vector::rbegin
        • (4)反向向迭代器 std::vector::rend
      • Capacity:
      • Element access:
      • Modifiers:
        • (2)assign
        • (3)std::vector::pop_back
        • (4)std::vector::insert(不能像string那样用下标插入了)头插
        • (5)erase 删
        • (6)emplace
      • Allocator:
      • Non-member function overloads
      • Template specializations
    • 拓展
      • 1.sting,vector区别
      • 用string实例化一个vector,使用范围for
      • vstr[][]和vstr.operator[]().operator[]()++两者等价
        • 扩容问题
        • 练习
            • 1
        • 2.杨辉三角
          • 在c语言上的逻辑
          • c++
          • vector 和vector<vector<int>>区别和动态二维数组理解
  • 2.vector深度剖析及模拟实现
    • 2.1 std::vector的核心框架接口的模拟实现st::vector
    • 2.2 使用memcpy拷贝问题
      • 2.2.1.浅拷贝
      • 2.2.2深拷贝
      • 深层次深浅拷贝问题
    • 补充
      • 迭代器失效问题(insert和erase)
        • 由于扩容引起野指针问题
      • 迭代器失效问题(erase)
        • 删除数据,导致数据挪动,it已经不是指向之前位置了。it也失效了,因为it已经不是指向之前的位置,可能会导致逻辑问题。
        • erase迭代器失效的复杂场景(要求删除所有的偶数)
          • 极端情况,erase下缩容
  • 总结

1.vector的介绍及使用(顺序表)

在这里插入图片描述

1.1 vector的介绍vector参考文献

在这里插入图片描述

三种遍历方式

(1)遍历第一种下标
(2)第二种迭代器
(3)范围for 支持迭代器就支持范围for

具体代码实现如下图:

vector<int> v1;
vector<int> v2(10, 1);
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
//遍历第一种下标
for (size_t i = 0; i < v1.size(); i++)
{
	cout << v1[i] << " ";
}
cout << endl;
//第二种迭代器
vector<int>::iterator it1 = v1.begin();//像指针一样的东西,在指定类域里操作
while (it1!=v1.end())
{
	cout << *it1 << " ";
	++it1;
}
cout << endl;
//范围for 支持迭代器就支持范围for
for (auto e : v1)
{
	cout << e<< " ";
}
cout << endl;

在这里插入图片描述

1.2 vector的使用

Member functions

(1) (constructor) std::vector::vector构造

在这里插入图片描述

vector<int> v1;
vector<int> v2(10, 1);
vector<int> v1 = { 1,2,3,4,5,6 };

上面的代码调用了下面这个:
在这里插入图片描述
在这里插入图片描述

void test_vector1()
{
	vector<int> v1 = { 1,2,3,4,5,6 };
	vector<int> v2  ({ 1,2,3,4,5,6 });
	auto il1 = { 1,2,3,4,5,6 };
	initializer_list<int> il2 = { 1,2,3,4,5,6 };
	//int a[] = { 1,2,3,4,5,6 };

 }

initializer_list底层有两个指针,如下图:
在这里插入图片描述

Iterators(迭代器):

(1)正向迭代器std::vector::begin

在这里插入图片描述

(2)正向迭代器std::vector::end

在这里插入图片描述

(3)反向向迭代器std::vector::rbegin

在这里插入图片描述

(4)反向向迭代器 std::vector::rend

在这里插入图片描述

Capacity:

在这里插入图片描述
一般最好不要使用shrink_to_fit接口,因为平常都是删除数据,不会改变空间大小(如下图)
在这里插入图片描述

Element access:

在这里插入图片描述

Modifiers:

####(1) push_back
在这里插入图片描述

具体使用在三种遍历方式那;

(2)assign

在这里插入图片描述

v1.assign({ 10,20,30 });
for (auto e : v1)
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

(3)std::vector::pop_back

在这里插入图片描述

(4)std::vector::insert(不能像string那样用下标插入了)头插

在这里插入图片描述

v1.insert(v1.begin(),10);
for (auto e : v1)
{
	cout << e << " ";
}
cout << endl;
v1.insert(v1.begin()+2, 1000);
for (auto e : v1)
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

(5)erase 删

在这里插入图片描述

v1.erase(v1.begin() + 2);
for (auto e : v1)
{
	cout << e << " ";
}
cout << endl;
}

在这里插入图片描述

(6)emplace

在这里插入图片描述

Allocator:

在这里插入图片描述

Non-member function overloads

在这里插入图片描述

Template specializations

在这里插入图片描述

拓展

1.sting,vector区别

1.类型不同

string s1;
vector<char> v3;

在这里插入图片描述
2、string定义的s1是有/0的,vector定义v3没有/0;
3.string能串,vector不行,string又operator[]+=…;vector 没有#

用string实例化一个vector,使用范围for

用string实例化一个vector底层原理(如下图)
在这里插入图片描述

vstr.push_back(“李四”);//隐式类型转换 在调用string(const char* str);
for (const auto& e : vstr)//v1不是int类型加const auto& ;不然消耗太大
这两个很重要

vector<string> vstr;//用string实例化一个vector
string s1 = "张三";
vstr.push_back(s1);
vstr.push_back("李四");//隐式类型转换 在调用string(const char* str);
for (const auto& e : vstr)//v1不是int类型加const auto& ;不然消耗太大
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

vstr[][]和vstr.operator.operator++两者等价

过程如下:
在这里插入图片描述

vstr[0][1]++;//变同音词
vstr[0][1]++;
vstr.operator.operator++;//与上方代码等价

//vstr[0][0]++;
vstr[0][1]++;//变同音词
vstr[0][1]++;
vstr.operator[](0).operator[](1)++;//与上方代码等价
for (const auto& e : vstr)//v1不是int类型加const auto& ;不然消耗太大
{
	cout << e << " ";
}
cout << endl;

在这里插入图片描述

扩容问题

capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2
倍增长的。

// 测试vector的默认扩容机制
void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

// 如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够
// 就可以避免边插入边扩容导致效率低下的问题了
void TestVectorExpandOP()
{
	vector<int> v;
	size_t sz = v.capacity();
	v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
	cout << "making bar grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}
int main()
{
	//test_vector1();
	TestVectorExpand();
	TestVectorExpandOP();
	return 0;
}

在这里插入图片描述

练习
1

在这里插入图片描述

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int value = 0;
        for(auto e:nums)
        {
            value ^= e;
        }
        return value;
    }
};
2.杨辉三角
在c语言上的逻辑

在这里插入图片描述
在这里插入图片描述

how 开辟空间的:

int row =0;
int *colArr = NULL;
ptr = generate(10,&row,&colArr);//int**  colArr为指针,再取地址;
int**ptr =(int**)malloc(sizeof(int*)*N);
for(int i  = 0;i<N ;i++)
{
ptr[i] =(int*)malloc(sizeof(int)*(i+1));
}
c++
class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> vv(numRows,vector<int>());
        for(size_t i =0;i<numRows;++i)
        {
            vv[i].resize(i+1,1);//全是1;
        }
        for(size_t i = 0;i < vv.size();++i)
        {
            for(size_t j = 1;j < vv[i].size()-1;++j)//第一个,最后一个不需要动
            {
             vv[i][j]=vv[i-1][j]+vv[i-1][j-1];//上一行的前一个和前一行的后一个相加
            }
        }
        return vv;

    }
};
vector 和vector<vector>区别和动态二维数组理解

本质实例化出两个类型
vector
vector<vector>

//vector
template<class T>
class vector
{
public:
    T& operator[](size_t i)
    {
        assert(i < _size);
            return _a[i];
    }
private:
    T* _a;
    size_t _size;
    size_t _capacity;
};

详细分解如下图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.vector深度剖析及模拟实现

2.1 std::vector的核心框架接口的模拟实现st::vector

vector.h

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace st
{
	template <class T>
	class vector
	{
	public:
		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()
			:_start(nullptr)
			, _finish(nullptr)
			, _endofstorage(nullptr)
		{}
		vector(initializer_list<T> il)
			:_start(nullptr)
			, _finish(nullptr)
			, _endofstorage(nullptr)
		{
			reserve(il.size());
			for (auto& e : il)//加引用,万一类型不是整形
			{
				push_back(e);
			}
		}
		~vector()
		{
			delete[]_start;
			_start = _finish = _endofstorage = nullptr;
		}
		T& operator[](size_t i)
		{
			assert(i < size());
			return _start[i];
		}
		const T& operator[](size_t i) const
		{
			assert(i < size());
			return _start[i];
		}
		size_t size() const
		{
			return _finish - _start;
		}
		size_t capacity() const
		{
			return _endofstorage - _start;
		}
		void resize(size_t n, T val = T())//匿名对象缺省值
		{
			if (n <= size())
			{
				_finish = _start + n;
			}
			else
			{
				reserve(n);
				while (_finish < _start + n)
				{
					*_finish = val;
					++_finish;
				}
			}
		}
		void reserve(size_t n)
		{
			if (n > capacity())
			{
				size_t Oldsize = size();
				T* tmp = new T[n];
				if (_start)
				{
					memcpy(tmp, _start, sizeof(T) * Oldsize);//拷贝
					delete[] _start;
				}
				_start = tmp;
				_finish = _start + Oldsize;
				_endofstorage = _start + n;
			}
		}
		void push_back(const T& x)
		{
			//复用
			//insert(_finish, x);//在finish这个位置插入x

			if (_finish == _endofstorage)
			{
				reserve(capacity() == 0 ? 4 : capacity() * 2);
			}
			*_finish = x;
			++_finish;
		}
		bool empty()
		{
			return _start == _finish;
		}
		void pop_back()//尾删
		{
			assert(!empty());//不能为空
			--_finish;
		}
		//迭代器失效,本质因为一些原因,迭代器不可用
		//void insert(iterator pos, const T& x)
		//{
		//	assert(pos >= _start && pos <= _finish);
		//	//空间不够,扩二倍
		//	if (_finish == _endofstorage)
		//	{
		//		size_t len = pos - _start;
		//		reserve(capacity() == 0 ? 4 : capacity() * 2);
		//		pos = _start + len;
		//	}
		//	iterator i = _finish - 1;
		//	while (i >= pos)
		//	{
		//		*(i + 1) = *i;
		//		--i;
		//	}
		//	*pos = x;
		//	++_finish;
		//}
		//修改
		iterator insert(iterator pos, const T& x)
		{
			assert(pos >= _start && pos <= _finish);
			//空间不够,扩二倍
			if (_finish == _endofstorage)
			{
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}
			iterator i = _finish - 1;
			while (i >= pos)
			{
				*(i + 1) = *i;
				--i;
			}
			*pos = x;
			++_finish;
			return pos;
		}
		iterator erase(iterator pos)
		{
			assert(pos >= _start);
			assert(pos < _finish);
			iterator i = pos + 1;
			while (i < _finish)
			{
				*(i - 1) = *i;//覆盖往后挪
				i++;
			}
			_finish --;
			return pos;
		}
	private:
		iterator _start;//头  _a
		iterator _finish;//尾  _finsh-_start ==_size
		iterator _endofstorage;//末  _endofstorage-_start ==_capacity;

	};
	void test_vector1()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);
		v1.push_back(6);
		for (size_t i = 0; i < v1.size(); i++)
		{
			cout << v1[i] << " ";
		}
		cout << endl;
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		vector<int>::iterator it1 = v1.begin();
		while (it1 != v1.end())
		{
			cout << *it1 << " ";
			++it1;
		}
		cout << endl;
		v1.pop_back();
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

	}
	void test_vector2()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		v1.insert(v1.begin() + 2, 30);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		vector<int> v2 = { 1,2,3,4,5,6,7 };
		for (auto e : v2)
		{
			cout << e << " ";
		}
		cout << endl;

	}

	void test_vector3()
	{
		std::vector<int> v1;
		//vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

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

		int x;
		cin >> x;
		auto it = find(v1.begin(), v1.end(), x);
		//if(it != v1.end())
		//{
		//	//it是否失效? 失效了,不能访问
		//	it = v1.insert(it, 10 * x);
		//	cout <<*it << endl;//失效了
		//}
		if (it != v1.end())
		{
			
			it  = v1.insert(it, 10 * x);
			cout << *it << endl;//失效了
		}
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

	}

	void test_vector4()
	{
		std::vector<int> v1;
		/*vector<int> v1;*/
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

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

		int x;
		cin >> x;
		auto it = find(v1.begin(), v1.end(), x);
		if (it != v1.end())
		{
			//it是否失效? 失效了,不能访问
			v1.erase(it);
			cout << *it << endl;

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

	}
	void test_vector5()
	{
		std::vector<int> v1;
		/*vector<int> v1;*/
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		//要求删除所有的偶数
		auto it = v1.begin();
		while (it != v1.end())
		{
			if (*it % 2 == 0)
			{
				//erase 返回删除位置下一个位置。
				it = v1.erase(it);
			}
			else ++it;
		}
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

	}

	void test_vector6()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
		v1.resize(10);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

		v1.resize(15,1);
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

}



test.cpp

#include<iostream>
#include<vector>
using namespace std;
void test_vector1()
{
	vector<int> v1{ 1,2,3,4,5,6 };
	vector<int> v2({ 1,2,3,4,5,6 });
	//auto il1 = { 1,2,3,4,5,6 };
	//initializer_list<int> il2 = {1,2,3,4,5,6};
	//int a[] = {1,2,3,4,5,6,7};
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	//v1[10]
	v1.assign({ 10,20,30 });
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	v1.insert(v1.begin() ,9);
for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	v1.insert(v1.begin() + 2, 200);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}
void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	cout << typeid(vector<int>::iterator).name() << endl;//查看类型
		sz = v.capacity();
		cout << "making v grow:\n";
		for (int i = 0; i < 100; ++i)
		{
			v.push_back(i);
			if (sz != v.capacity())
			{
				sz = v.capacity();
				cout << "capacity changed:" << sz << '\n';

			}
		}

}

void test_vector2()
{
	
	TestVectorExpand();
}
#include"vector.h"
int main()
{
	//test_vector1();
	//st::test_vector2();
	/*st::test_vector3();*/
	/*st::test_vector4();*/
	/*st::test_vector5();
	int i = int();
	int i = int(1);
	int k(2);*/
	st::test_vector6();
	return 0;
}

2.2 使用memcpy拷贝问题

2.2.1.浅拷贝

在这里插入图片描述

2.2.2深拷贝

vector.h

//深拷贝 拷贝构造 v2(v1)
vector(const vector<T>& v)
{
	reserve(v.capacity());
	for (auto& e : v)
	{
		push_back(e);
	}
}
void swap(vector<T>& tmp)
{
	std::swap(_start, tmp._start);
	std::swap(_finish, tmp._finish);
	std::swap(_endofstorage, tmp._endofstorage);
}
// v1 = v3 现代写法
vector <T>& operator = (vector<T> v)
{
	swap(v);    //v3是v想要的,v是v1想要的直接交换
	return *this;
}
~vector()
......................................................................................
void test_vector7()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	//值拷贝,浅拷贝
	vector<int> v2(v1);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	vector<int>v3 = { 10,20,30,40 };
	v1 = v3;
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

在这里插入图片描述

深层次深浅拷贝问题

下方是浅拷贝的代码段和过程,问题是出在memcpy,string中,_str指针指向的内容会析构两次,乱码。
在这里插入图片描述

在这里插入图片描述
下面是深拷贝过程及修改

void reserve(size_t n)
{
	if (n > capacity())
	{
		size_t Oldsize = size();
		T* tmp = new T[n];
		if (_start)
		{
			//memcpy(tmp, _start, sizeof(T) * Oldsize);//拷贝
			for (size_t i = 0; i < Oldsize; i++)
			{
				tmp[i] = _start[i];//赋值 是深拷贝
			}
			delete[] _start;
		}
		_start = tmp;
		_finish = _start + Oldsize;
		_endofstorage = _start + n;
	}
}

在这里插入图片描述

补充

迭代器失效问题(insert和erase)

由于扩容引起野指针问题

在这里插入图片描述
在这里插入图片描述

	void test_vector3()
	{
		std::vector<int> v1;
		//vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

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

		int x;
		cin >> x;
		auto it = find(v1.begin(), v1.end(), x);
		//if(it != v1.end())
		//{
		//	//it是否失效? 失效了,不能访问
		//	it = v1.insert(it, 10 * x);
		//	cout <<*it << endl;//失效了
		//}
		if (it != v1.end())
		{
			
			it  = v1.insert(it, 10 * x);
			cout << *it << endl;//失效了
		}
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

	}
}

迭代器失效问题(erase)

任何场景下,迭代器都会失效,要更新后再去访问。eg:修改后的代码段//erase 返回删除位置下一个位置。

删除数据,导致数据挪动,it已经不是指向之前位置了。it也失效了,因为it已经不是指向之前的位置,可能会导致逻辑问题。

erase模拟实现的过程如下:
在这里插入图片描述
在这里插入图片描述

vs报错的原因:强制的检查,失效迭代器不让你访问。

void test_vector4()
{
	std::vector<int> v1;
	/*vector<int> v1;*/
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

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

	int x;
	cin >> x;
	auto it = find(v1.begin(), v1.end(), x);
	if (it != v1.end())
	{
		//it是否失效? 失效了,不能访问
		v1.erase(it);
		cout << *it << endl;

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

}

在这里插入图片描述

erase迭代器失效的复杂场景(要求删除所有的偶数)
void test_vector5()
{
	std::vector<int> v1;
	/*vector<int> v1;*/
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	//要求删除所有的偶数
	auto it = v1.begin();
	while (it != v1.end())
	{
		if (*it % 2 == 0)
		{
			v1.erase(it);
		}
		++it;
	}
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

}

在这里插入图片描述
修改后

//要求删除所有的偶数
auto it = v1.begin();
while (it != v1.end())
{
	if (*it % 2 == 0)
	{
		//erase 返回删除位置下一个位置。
		it = v1.erase(it);
	}
	else ++it;
}

在这里插入图片描述

极端情况,erase下缩容

在这里插入图片描述

总结

以上就是vector的全部内容了,写了好多天,一次没看懂,可多次阅读文章。喜欢博主写的内容,可以一键三连支持博主。

相关文章:

  • 使用Azure CDN进行子域名接管
  • 解锁 DeepSeek 安全接入、稳定运行新路径
  • vulhub-joker攻略
  • VulnHub-Billu_b0x通关攻略
  • 【C++】多态
  • CCF-CSP认证 202206-1归一化处理
  • Compose 的产生和原理
  • MySQL超详细介绍(近2万字)
  • 穆迪暖色调人像静物摄影后期Lr调色教程,手机滤镜PS+Lightroom预设下载!
  • 生成PDF文件:从html2canvas和jsPdf渲染到Puppeteer矢量图
  • Android Handler 通过线程安全的 MessageQueue 和底层唤醒机制实现跨线程通信
  • 【嵌入式学习】如何利用gitee管理记录学习内容
  • 多线程—进程与线程
  • 【软考-架构】8.2、开发方法-TPC-MIS-DSS
  • RSI 量化策略实战指南:基于 iTick 报价源的 Python 实现
  • 卷积神经网络 - 卷积层
  • 库的制作与原理 linux第课
  • LORA的AB矩阵是针对Transformer的多头还是MLP
  • 台式机电脑组装---电脑机箱与主板接线
  • 线程池的拒绝策略适用场景思考
  • 一季度全国消协组织为消费者挽回经济损失23723万元
  • “用鲜血和生命凝结的深厚情谊”——习近平主席署名文章中的中俄友好故事
  • 习近平向“和平薪火 时代新章——纪念中国人民抗日战争和苏联伟大卫国战争胜利80周年中俄人文交流活动”致贺信
  • 华为招聘:未与任何第三方开展过任何形式的实习合作
  • 印官员称巴基斯坦在克什米尔实控线附近开火已致7死38伤
  • 刘诚宇、杨皓宇进球背后,是申花本土球员带着外援踢的无奈