【C++从0到王者】第十四站:list基本使用及其介绍

news2024/10/6 16:21:51

文章目录

  • 一、list基本介绍
  • 二、list基本使用
    • 1.尾插头插接口使用
    • 2.insert接口使用
    • 3.查找某个值所在的位置
    • 4.erase接口使用以及迭代器失效
    • 5.reverse
    • 6.sort
    • 7.merge
    • 8.unique
    • 9.remove
    • 11.splice
  • 三、list基本使用完整代码

一、list基本介绍

如下所示,是库里面对list的基本介绍
在这里插入图片描述

链表是序列容器,允许在序列内的任何位置进行常量时间的插入和擦除操作,以及两个方向的迭代。

链表容器被实现为双链表;双链表可以将它们包含的每个元素存储在不同且不相关的存储位置。排序是通过与前面元素的链接和后面元素的链接的每个元素的关联在内部保持的。

它们与forward_list非常相似:主要区别在于forward_list对象是单链表,因此它们只能向前迭代,以换取更小和更高效。

与其他基本标准序列容器(array、vector和deque)相比,链表在容器内的任何位置插入、提取和移动元素(迭代器已经获得)方面通常表现更好,因此在大量使用链表的算法(如排序算法)中也表现更好。

与其他序列容器相比,列表和forward_lists的主要缺点是它们无法通过位置直接访问元素;例如,要访问链表中的第六个元素,必须从已知位置(如开始或结束)迭代到该位置,这需要在两者之间的距离上花费线性时间。它们还消耗一些额外的内存来保存与每个元素相关联的链接信息(对于包含小元素的大型列表来说,这可能是一个重要因素)。

在这里插入图片描述

二、list基本使用

我们先简单的使用一下一下list,list的使用与vector基本是一致的,需要注意的是,对于list是没有[]运算符去访问的,因为其底层是一个双向带头循环链表。

1.尾插头插接口使用

void testlist1()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	lt.push_front(7);
	lt.push_front(8);


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

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

在这里插入图片描述

2.insert接口使用

从下面,我们已经看出来,对于list它的接口已经全部是迭代器去访问了,可以是在某个迭代器处插入一个值,可以是插入n个val,也可以是插入一个迭代器区间
在这里插入图片描述
在这里需要注意的是,由于list本身是一个链表的特性,所以如果想要在第五个位置插入一个值,以下写法是错误的。如果是vector确实可以这样插入
在这里插入图片描述

如果是我们自己去写这个list的话,我们可以加上这个运算符重载,但是库里面觉得这个代价太大,所以没有加

但是如果非要在第五个位置处插入,我们可以这样写,这样直接插入的代价是比较低的,因为其只需要改变连接关系即可

void testlist2()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	list<int>::iterator it = lt.begin();
	for (int i = 0; i < 5; i++)
	{
		it++;
	}
	lt.insert(it, 10);
	it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}

在这里插入图片描述

3.查找某个值所在的位置

其实在C++中list并没有直接提供这个接口,这是因为C++中是将容器和算法进行了分离。而这两个是通过迭代器进行连接起来的。
在这里插入图片描述

因为迭代器并不暴露容器底层的细节。就能让算法直接访问容器里面的元素。
在这里插入图片描述

注意库里面使用的是不等于,而非小于,这是为了适应其他各种各样的容器而设置的

比如list容器中,如果不采用这种设计结构,那么由于本来每个地址都是离散的,并不能确保每个结点的地址究竟是如何的,而产生严重的错误。
在这里插入图片描述

我们现在来使用一下

void testlist3()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	list<int>::iterator pos = find(lt.begin(), lt.end(), 3);
	lt.insert(pos, 300);

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

在这里插入图片描述

那么我们现在再来探讨一下,vector里使用insert后会存在失效问题,那么链表中还有吗。

我们可以测试一下

在这里插入图片描述

测试结果显示,迭代器并未失效,其实这里也挺好理解的,因为list的insert中它是一个结点一个结点的插入进去。而vector里则是看容量的,容量不够扩容时候,需要整体将空间移动位置,才导致的迭代器失效。而list不存在扩容问题。是不会将之前的数据都给换位置的。故而不导致迭代器失效。

4.erase接口使用以及迭代器失效

如下所示,erase可以删除某个迭代器位置的值,也可以删除某一个迭代器区间。
在这里插入图片描述

erase的使用很简单,我们这里主要研究以下,erase是否存在迭代器失效问题呢?其实是存在的,因为erase删除某一个结点后,由于list是离散的,所以之前的那个pos已经无法找到其他的结点的,这个迭代器已经是一个野指针了。故而失效。但是同样的库里面的解决方法就是增加一个返回值,返回已删除元素的下一个元素迭代器。
在这里插入图片描述

当我们想要删除所有的偶数的时候,我们也很容易的可以写出以下代码
在这里插入图片描述

5.reverse

注意了啊,这里是逆置,不是reserve(扩容)

这个接口的作用就是逆置链表
在这里插入图片描述

list里面虽然设计了这个接口,但是事实上这个接口是没有必要涉及的,有一点冗余,因为在算法库里面也设计了这个算法。而且这两个算法的思路是一模一样的
在这里插入图片描述

如下是测试代码

void testlist4()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	lt.reverse();
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	reverse(lt.begin(), lt.end());
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
}

在这里插入图片描述

6.sort

如下是list里面的sort,可以直接排升序或者降序,使用很方便
在这里插入图片描述

但是算法库里面也设计了一个sort,但是这个是冗余的吗?先说结论,算法库里面的sort对于list而言是用不了的。会直接报错
在这里插入图片描述

不相信的话,我们可以测试一下
在这里插入图片描述
那么为什么用不了呢?我们可以深入去查看一下
我们从错误列表里面可以定位到是这里报错了
在这里插入图片描述

算法库里面使用的是快排,快排是无法适应list里面的这个场景的。

事实上,我们不难注意到,在算法库中,虽然每个算法都是一个函数模板,但是函数模板的迭代器名字有所差异
在这里插入图片描述

事实上,这是因为我们对迭代器从功能上进行了分类。注意这里的是由迭代器的性质(容器的底层结构决定的),从而进行的划分。他是一个隐式的划分
在这里插入图片描述

而上面的模板参数中对于迭代器的分类其实也显而易见了,Input就是所有迭代器都可以去用的。Bid这种迭代器就适合双向的迭代器去调用。Radom就适合随机迭代器去使用。

所以list适合双向迭代器,用不了随机的。

那么我们怎么知道哪个容器是哪种类型的呢?其实库里面已经全部说了

下面是list的迭代器
在这里插入图片描述

注意上面的不是彻底定死了,比如vector是随机迭代器,但他可以认为是特殊的双向迭代器。所以也是可以调用reverse接口的。
在这里插入图片描述
下面是vector的迭代器
在这里插入图片描述

再比如库里面也有单链表,forward_list,就是一个典型的单向迭代器
在这里插入图片描述

所以现在我们就清楚了为什么不能使用算法库里面的sort了,所以链表里面的sort就有点意义了。

当然呢,也只是有点意义罢了,其实也没有多大意义,为什么这么说呢?因为如果我们把list的数据拷贝给一个vector,然后用vector去排序,我们会发现,vector的效率远远高于list的效率

我们可以用如下代码去测试一下:注意需要在release环境下去测试,因为debug下有很多调试信息会影响两个的实际速度

void testlist5()
{
	srand(time(0));
	const int N = 1000000;
	vector<int> v; 
	v.reserve(N);
	list<int> lt1;
	list<int> lt2;

	for (int i = 0; i < N; ++i)
	{
		auto e = rand();
		lt2.push_back(e);
		lt1.push_back(e);
	}
	// 拷贝到vector排序,排完以后再拷贝回来
	int begin1 = clock();
	// 先拷贝到vector
	for (auto e : lt1)
	{
		v.push_back(e);
	}
	// 排序
	sort(v.begin(), v.end());

	// 拷贝回去
	size_t i = 0;
	for (auto& e : lt1)
	{
		e = v[i++];
	}

	int end1 = clock();

	int begin2 = clock();
	lt2.sort();
	int end2 = clock();

	printf("vector sort:%d\n", end1 - begin1);
	printf("list sort:%d\n", end2 - begin2);
}

在这里插入图片描述

可见确实vector要优于list。因为库里面用的是快排,list里面用的是归并。快排还是要稍微优于归并一点的。

7.merge

如下所示,它的作用其实就是两个链表进行归并,注意归并前必须先进行排序
在这里插入图片描述

// list::merge
#include <iostream>
#include <list>

// compare only integral part:
bool mycomparison(double first, double second)
{
    return (int(first) < int(second));
}

int main()
{
    std::list<double> first, second;

    first.push_back(3.1);
    first.push_back(2.2);
    first.push_back(2.9);

    second.push_back(3.7);
    second.push_back(7.1);
    second.push_back(1.4);

    first.sort();
    second.sort();

    first.merge(second);

    // (second is now empty)

    second.push_back(2.1);
    for (auto e : second)
    {
        std::cout << e << " ";
    }
    std::cout << std::endl;
    first.merge(second, mycomparison);

    std::cout << "first contains:";
    for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

如下是运行结果,我们可以发现一些现象,首先是归并之后,second的结点都被归并走了,它里面也就没有数据了。
注意,在第二次合并中,函数mycomparison没有考虑2.1比2.2或2.9低,因为进行了强制类型转换,所以它被插入到它们之后,在3.1之前。
在这里插入图片描述

8.unique

这个函数的功能是去重,但是要注意首先得先进行排序,才能进行去重。否则效率极低
在这里插入图片描述

9.remove

remove其实相当于find+erase。先找到要移除的结点,然后删除掉。
在这里插入图片描述如下代码所示

void testlist6()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	lt.remove(3);
	lt.remove(10);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
}

找到3以后,移除掉这个结点,如果这个值不存在,即找不到,就什么也不做。
在这里插入图片描述

11.splice

这个是粘接、转移的意思,它可以将一个链表的某个结点拿走,交给另外一个链表
在这里插入图片描述

这三个函数的意思分别是,第一个函数是,将x链表全部转移到该链表的pos位置之前,第二个函数是将x链表的i结点转移到pos之前,第三个函数是,将x链表的某个迭代器区间,转移到pos之前。

如下代码所示,是该函数可以使用的情形

void testlist7()
{
	list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);

	list<int> lt2;
	lt2.push_back(10);
	lt2.push_back(20);
	lt2.push_back(30);

	list<int> lt3;
	lt3.push_back(100);
	lt3.push_back(200);
	lt3.push_back(300);
	for (auto e : lt1)
	{
		cout << e << " ";
	}	
	cout << endl;

	for (auto e : lt2)
	{
		cout << e << " ";
	}
	cout << endl;
	list<int>::iterator it = lt1.begin();
	it++;
	lt1.splice(it, lt2);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	list<int>::iterator it3 = lt3.begin();
	it3++;
	lt1.splice(it, lt3, it3);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;


	lt1.splice(it, lt3, lt3.begin(), lt3.end());
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	it = lt1.begin();
	lt1.splice(it, lt1, ++lt1.begin(), lt1.end());
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;
}

在这里插入图片描述

三、list基本使用完整代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<algorithm>
#include<list>
#include<vector>
using namespace std;

void testlist1()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	lt.push_front(7);
	lt.push_front(8);


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

	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
}
void testlist2()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	list<int>::iterator it = lt.begin();
	for (int i = 0; i < 5; i++)
	{
		it++;
	}
	lt.insert(it, 10);
	it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}
void testlist3()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	list<int>::iterator pos = find(lt.begin(), lt.end(), 3);
	lt.insert(pos, 300);
	*pos *= 10;
	list<int>::iterator it = lt.begin();
	it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	//lt.erase(pos);
	//*pos = 10;

	it = lt.begin();
	while (it != lt.end())
	{
		if (*it % 2 == 0)
		{
			it = lt.erase(it);
		}
		else
		{
			it++;
		}
	}
	it = lt.begin();

	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}
void testlist4()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	lt.reverse();
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	reverse(lt.begin(), lt.end());
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	//sort(lt.begin(), lt.end());
}


void testlist5()
{
	srand(time(0));
	const int N = 1000000;
	vector<int> v; 
	v.reserve(N);
	list<int> lt1;
	list<int> lt2;

	for (int i = 0; i < N; ++i)
	{
		auto e = rand();
		lt2.push_back(e);
		lt1.push_back(e);
	}
	// 拷贝到vector排序,排完以后再拷贝回来
	int begin1 = clock();
	// 先拷贝到vector
	for (auto e : lt1)
	{
		v.push_back(e);
	}
	// 排序
	sort(v.begin(), v.end());

	// 拷贝回去
	size_t i = 0;
	for (auto& e : lt1)
	{
		e = v[i++];
	}

	int end1 = clock();

	int begin2 = clock();
	lt2.sort();
	int end2 = clock();

	printf("vector sort:%d\n", end1 - begin1);
	printf("list sort:%d\n", end2 - begin2);
}

void testlist6()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	lt.remove(3);
	lt.remove(10);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
}
void testlist7()
{
	list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);

	list<int> lt2;
	lt2.push_back(10);
	lt2.push_back(20);
	lt2.push_back(30);

	list<int> lt3;
	lt3.push_back(100);
	lt3.push_back(200);
	lt3.push_back(300);
	for (auto e : lt1)
	{
		cout << e << " ";
	}	
	cout << endl;

	for (auto e : lt2)
	{
		cout << e << " ";
	}
	cout << endl;
	list<int>::iterator it = lt1.begin();
	it++;
	lt1.splice(it, lt2);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	list<int>::iterator it3 = lt3.begin();
	it3++;
	lt1.splice(it, lt3, it3);
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;


	lt1.splice(it, lt3, lt3.begin(), lt3.end());
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	it = lt1.begin();
	lt1.splice(it, lt1, ++lt1.begin(), lt1.end());
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;
}
int main()
{
	testlist7();
	return 0;
}
















//
// list::merge
//#include <iostream>
//#include <list>
//
// compare only integral part:
//bool mycomparison(double first, double second)
//{
//    return (int(first) < int(second));
//}
//
//int main()
//{
//    std::list<double> first, second;
//
//    first.push_back(3.1);
//    first.push_back(2.2);
//    first.push_back(2.9);
//
//    second.push_back(3.7);
//    second.push_back(7.1);
//    second.push_back(1.4);
//
//    first.sort();
//    second.sort();
//
//    first.merge(second);
//
//     (second is now empty)
//
//    second.push_back(2.1);
//    for (auto e : second)
//    {
//        std::cout << e << " ";
//    }
//    std::cout << std::endl;
//    first.merge(second, mycomparison);
//
//    std::cout << "first contains:";
//    for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)
//        std::cout << ' ' << *it;
//    std::cout << '\n';
//
//    return 0;
//}


好了,本期内容就到这里了

如果对你有帮助的话,不要忘记点赞加收藏哦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自然语言处理学习笔记(一)————概论

目录 1.自然语言处理概念 2.自然语言与编程语言的比较 &#xff08;1&#xff09;词汇量&#xff1a; &#xff08;2&#xff09;结构化&#xff1a; &#xff08;3&#xff09;歧义性&#xff1a; &#xff08;4&#xff09;容错性&#xff1a; &#xff08;5&#xff0…

【143. 重排链表】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给定一个单链表 L 的头节点 head &#xff0c;单链表 L 表示为&#xff1a; L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为&#xff1a; L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不…

Redis (一)消息订阅和发送测试

〇、redis 配置 1、概况 本文基于 Ubuntu20.04 云服务器配置Redis&#xff0c;且在本地进行 Redis 测试。 2、目录概况 一、配置文件 位于 /config/app.yml 中&#xff0c;目的用于 Redis 初始化&#xff1a; redis:addr: "39.104.**.28:6379"password: "p…

盛元广通实验室教学仪器设备综合信息管理系统LIMS

实验室作为学生以及教师进行科研教学环境&#xff0c;对于实验室设备的使用情况、维护、借还、台账管理、盘点、报废等需要得到有效的管理&#xff0c;以促进科研教学工作的高质量开展&#xff0c;介于传统手动管理方式越发不能满足现代科研的飞速发展需要&#xff0c;实验室的…

【element-plus】 table表格每行圆角解决方案 element也通用

系列文章目录 【Vue3ViteTselement-plus】使用tsx实现左侧栏菜单无限层级封装 前言 我们在使用element-plus或element 的table时是否有时UI给到的UI效果是如下面这样的&#xff0c;但是我们翻遍了组件库的文档 调整了很多次样式 发现在 左右侧栏固定的时候 普通的方法是完全…

二阶阻尼弹簧系统的simulink仿真(s函数)

文章目录 前言一.非线性反步法1.原系统对应的s函数脚本文件&#xff08;仅修改模板的初始化函数、导数函数和输出函数三个部分&#xff09;2.控制器对应的s函数脚本文件&#xff08;仅修改模板的初始化函数和输出函数两个部分&#xff09;3.其他参数脚本文件4.输入5.输出&#…

【Git系列】分支操作

&#x1f433;分支操作 &#x1f9ca;1. 什么是分支&#x1f9ca;2. 分支的好处&#x1f9ca;3. 分支操作&#x1fa9f;3.1 查看分支&#x1fa9f;3.2 创建分支&#x1fa9f;3.3 切换分支 &#x1f9ca;4. 分支冲突&#x1fa9f;4.1 环境准备&#x1fa9f;4.2 分支冲突演示 &am…

NPP及碳源、碳汇模拟,python蒸散发与植被总初级生产力估算

CASA模型是一个基于过程的遥感模型(Potteret al&#xff0c;1993&#xff1b;Potter et al&#xff0c;1994)&#xff0c;耦合了生态系统生产力和土壤碳、氮通量&#xff0c;由网格化的全球气候、辐射、土壤和遥感植被指数数据集驱动。模型包括土壤有机物、微量气体通量、养分利…

DelphiZXingQRCode 库:轻松集成二维码生成功能到 Delphi 项目中

一、下载地址&#xff1a;GitHub - foxitsoftware/DelphiZXingQRCode: Delphi port of QR Code functionality from ZXing, a barcode image processing library. 二、使用步骤&#xff1a; 1&#xff09;引用单元文件。 //引用单元 usesDelphiZXIngQRCode2&#xff09;编写…

AD21 PCB设计的高级应用(五)模块复用的操作

&#xff08;五&#xff09;模块复用的操作 1.利用Room实现相同模块复用2.复制粘贴功能实现模块复用 1.利用Room实现相同模块复用 本小节介绍 Altium Designer 两种常用模块复用方法:一种是利用 Room 实现相同模块复用,另一种是利用复制粘贴功能实现。 1.利用Room实现相同模块…

《面试1v1》Kafka的ack机制

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

数组的使用(逆序、冒泡)

内存连续数据类型相同从0开始索引 找出数组中的最大值 #include <iostream> #include <stdlib.h> //随机数所在文件 using namespace std;int main() {int arr[5]{104,134,145,129,89};//初始化没有填的为0 int max0;for(int i0;i<5;i){if(arr[i]>max){ma…

算法综合篇专题一:双指针问题

"就算没有看清那株灿烂的花蕊&#xff0c;也应该放声歌颂赞美鲜红的玫瑰" 1、移动零 (1) 题目解析 (2) 算法原理 class Solution { public:void moveZeroes(vector<int>& nums) {for(int cur0,dest-1;cur<nums.size();cur){if(nums[cu…

【Unity造轮子】实现一个类csgo的武器轮盘功能

文章目录 前言素材导入开始1.放背景和中间的圆圈&#xff0c;调整合适的宽高和位置2.添加选择图像框3.添加一些武器道具选择4.书写脚本RadialMenuManager5.绑定脚本和对象6.运行效果&#xff0c;按tab键开启关闭轮盘7.优化添加显示选中的武器文本8.添加鼠标选中放大的效果9.添加…

ModaHub魔搭社区:国产大模型名录和产品信息一览表114个

取名类型 公司名 大模型名字 序号 旧词新组 百度 文心一言 1 阿里 通义千问 2 知乎 知海图 3 云知声 山海 4 中国科学院计算技术研究所 百聆

算法通过村第二关-链表青铜笔记

文章目录 再战链表|反转链表剑指 Offer II 024. 反转链表熟练掌握这两种解法建立头节点的解决思路不采用建立头节点的方法采用循环/递归的方式解决 总结 再战链表|反转链表 提示&#xff1a;多拿些酒来&#xff0c;因为生命只有乌有。 剑指 Offer II 024. 反转链表 如果不使用…

Excel修改日期格式,改变日期的筛选方式

我们有两列日期数据&#xff1a; 左边这一列筛选会显示&#xff1a; 右边这一列筛选会显示&#xff1a; 修改格式&#xff0c;将【日期1】改为【日期2】 将【日期1】的格式修改为文本格式即可 修改格式&#xff0c;将【日期2】改为【日期1】 选中日期2&#xff0c;点击【数据…

实用调试技巧(1)

什么是bug&#xff1f;调试是什么&#xff1f;有多重要&#xff1f;debug和release的介绍。windows环境调试介绍。一些调试的实例。如何写出好&#xff08;易于调试&#xff09;的代码。编程常见的错误。 什么是Bug 我们在写代码的时候遇到的一些问题而导致程序出问题的就是Bu…

C语言——函数栈帧的创建和销毁

Hello&#xff0c;好久没有写博客了&#xff0c;前两份都是之前写的&#xff0c;看来最近有点懈怠&#xff0c;最近也得快点找回学习的状态&#xff0c;那今天开始我们新的讲解 在我们刚开始学习C语言的时候&#xff0c;不知道大家有没有困惑&#xff0c;比如我们在使用局部变量…

vue 表单form-item模板(编辑,查看,新建)

目录 formatFormData 后端数据格式​编辑 JSON解析和生成 加载&#xff08;请求前&#xff0c;await后&#xff09; formComp formatFormData 后端数据格式 为空的&#xff0c;可以直接不提交/提交null/undefined JSON解析和生成 var str {"name": "…