C++STL剖析(七)—— map和multimap的概念和使用

news2024/11/22 15:26:38

文章目录

  • 1. map的介绍和使用
    • 🍑 map的模板参数列表
    • 🍑 map的构造
    • 🍑 map的使用
      • 🍅 insert
      • 🍅 operator[ ]
      • 🍅 find
      • 🍅 erase
      • 🍅 swap
      • 🍅 empty
      • 🍅 size
      • 🍅 count
    • 🍑 总结
  • 2. multimap的介绍和使用
    • 🍑 multimap的使用
      • 🍅 find
      • 🍅 count
    • 🍑 总结
  • 3. 前K个高频单词


1. map的介绍和使用

map 的介绍:

  • map 是关联容器,它按照特定的次序(按照 key 来比较)存储由键值 key 和值 value 组合而成的元素。
  • 在 map 中,键值 key 通常用于排序和唯一的标识元素,而值 value 中存储与此键值 key关联的内容。键值 key 和值 value 的类型可能不同,并且在 map 的内部,key 与 value 通过成员类型 value_type 绑定在一起,为其取别名称为 pairtypedef pair<const key, T> value_type;
  • 在内部,map 中的元素总是按照键值 key 进行比较排序的。
  • map 中通过键值访问单个元素的速度通常比 unordered_map 容器慢,但 map 允许根据顺序对元素进行直接迭代(即对 map 中的元素进行迭代时,可以得到一个有序的序列)。
  • map 支持下标访问符,即在 [] 中放入 key,就可以找到与 key 对应的 value。
  • map 通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

🍑 map的模板参数列表

如下图所示:

在这里插入图片描述

  • key:键值对中 key 的类型
  • T: 键值对中 value 的类型
    Compare:比较器的类型,map 中的元素是按照 key 来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
  • Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器

🍑 map的构造

主要有下面 3 种构造方式:

在这里插入图片描述

(1)指定 key 和 value 的类型构造一个空容器

// 构造一个key为string类型,value为int类型的空容器
map<string, int> m1;

(2)拷贝构造某类型容器

// 拷贝构造key为string类型,value为int类型的m1容器的复制品
map<string, int> m2(m1); 

(3)使用迭代器区间进行初始化构造

// 使用迭代器拷贝构造m2容器某段区间的复制品
map<string, int> m3(m2.begin(), m2.end());

🍑 map的使用

map 的接口虽然比较多,但是常用的也就那么几个。

🍅 insert

在 map 中插入键值对 x,注意 x 是一个键值对,返回值也是键值对

iterator 代表新插入元素的位置,bool 代表是否插入成功

在这里插入图片描述

在 map 的内部,key 与 value 通过成员类型 value_type 绑定在一起,为其取别名称为 pair

typedef pair<const key, T> value_type;

下面对于 insert 的插入有两种方式。

(1)使用 pair 直接来构造键值对

void testmap()
{
	map<string, string> dict;

	// 调用pair的构造函数,构造一个匿名对象插入
	dict.insert(pair<string, string>("sort", "排序"));
	dict.insert(pair<string, string>("root", "根"));
	dict.insert(pair<string, string>("left", "左边"));

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

可以看到插入的英文是按照升序进行排列的。

在这里插入图片描述

(2)使用 make_pair 函数来构造键值对

构造一个第一个元素设为 x,第二个元素设为 y 的pair对象。

模板类型可以从传递给 make_pair 的参数隐式推导出来。

如果各自的类型可以隐式转换,则可以从包含不同类型的其他 Pair 对象构造 Pair 对象。

在这里插入图片描述

代码示例

void testmap()
{
	map<string, string> dict;

	// 调用make_pair的构造函数,构造一个匿名对象插入
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("root", "根"));
	dict.insert(make_pair("left", "左边"));
	dict.insert(make_pair("up", "上面"));

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

推荐使用这种方式插入数据

在这里插入图片描述

(3)统计水果出现的次数

还记得在二叉查找树这篇文章种我们写了一个统计水果出现次数的代码吗?那么现在就可以用 map 来实现了

代码示例

void testmap()
{
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };

	map<string, int> countFruit;
	for (auto& str : arr)
	{
		map<string, int>::iterator it = countFruit.find(str);
		if (it != countFruit.end())
		{
			it->second++;
		}
		else
		{
			countFruit.insert(make_pair(str, 1));
		}
	}

	// 遍历
	for (const auto& kv : countFruit)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
}

可以看到水果出现的次数已经被打印出来了

在这里插入图片描述

但是代码还可以进行优化,我们知道 insert 的返回值是 pair<iterator, bool>

  • 其中第一个成员 iteratorpair::first) 是指向新插入元素或映射中具有等效键的元素的迭代器。
  • 第二个成员 boolpair::second)是返回插入成功与否的结果
    • 若待插入元素的键值 key 在 map 当中不存在,则 insert 函数插入成功,并返回插入后元素的迭代器和 true。
    • 若待插入元素的键值 key 在 map 当中已经存在,则 insert 函数插入失败,并返回 map 当中键值为 key 的元素的迭代器和 false。

代码示例

void testmap()
{
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };

	map<string, int> countFruit;
	for (auto& str : arr)
	{
		pair<map<string, int>::iterator, bool> ret = countFruit.insert(make_pair(str, 1));
		// auto ret = countFruit.insert(make_pair(str, 1)); // 也可以写成auto
		if (ret.second == false)
		{
			ret.first->second++; // ret.first是插入位置的迭代器,通过迭代器去访问second
		}
	}

	// 遍历
	for (const auto& kv : countFruit)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
}

运行可以看到是一样滴

在这里插入图片描述

🍅 operator[ ]

返回 key 对应的 value:

  • 如果 k 与容器中元素的键匹配,则函数返回对其映射值的引用。
  • 如果 k 与容器中任何元素的键不匹配,该函数将插入一个具有该键的新元素,并返回对其映射值的引用。

在这里插入图片描述

对这个函数的调用相当于:

(*((this->insert(make_pair(k,mapped_type()))).first))

operator[] 的原理就是:

  • <key, T()> 构造一个键值对,然后调用 insert() 函数将该键值对插入到 map 中
  • 如果 key 已经存在,插入失败,insert 函数返回该 key 所在位置的迭代器
  • 如果 key 不存在,插入成功,insert 函数返回新插入元素所在位置的迭代器
  • operator[] 函数最后将 insert 返回值键值对中的 value 返回

代码示例一

void testmap()
{
	map<string, string> dict;
	
	// 用make_pair函数来构造键值对
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("root", "根"));
	dict.insert(make_pair("left", "左边"));
	
	dict["up"] = "向上"; // up不存在,那么就插入up元素并修改(插入+修改)
	dict["left"] = "剩余"; // left存在,那么只修改(查找+修改)
	dict["erase"]; // erase不存在,那么插入
	
	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

运行结果

在这里插入图片描述

对于上面统计水果的次数,其实比较常用的就是 operator[]

void testmap()
{
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };

	map<string, int> countFruit;
	for (auto& str : arr)
	{
		countFruit[str]++; 
	}

	// 遍历
	for (const auto& kv : countFruit)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
}

运行结果

在这里插入图片描述

如果水果是第一次出现,那么就先插入,因为是第一次出现,所以水果的次数为0,插入成功以后,会把插入的这个水果所在的节点里面的次数进行引用返回,也就是返回 0 的引用,那么此时进行 ++,变成 1

如果水果是第二次出现,那么不会插入成功,那么就直接返回这个水果所在的节点迭代器里面的次数,然后再进行 ++ 变成 2。

注意:这里的 [] 不支持随机访问!

🍅 find

在容器中搜索键值等于 k 的元素,如果找到则返回该元素的迭代器,否则返回 map::end 的迭代器。

在这里插入图片描述

代码示例

void testmap()
{
	map<string, string> dict;
	
	// 用make_pair函数来构造键值对
	dict["sort"] = "排序";
	dict["up"] = "向上";;
	dict["left"] = "左边";
	dict["root"] = "根";
	
	auto pos = dict.find("root");
	if (pos != dict.end())
	{
		cout << "找到了" << endl;
		cout << pos->first << ":" << pos->second << endl;
	}
}

运行结果

在这里插入图片描述

🍅 erase

从 map 容器中移除单个元素或一组元素。

在这里插入图片描述

(1)从 map 容器中移除单个元素

void testmap()
{
	map<string, string> dict;

	// 用make_pair函数来构造键值对
	dict["sort"] = "排序";
	dict["up"] = "向上";;
	dict["left"] = "左边";
	dict["root"] = "根";

	auto pos = dict.find("root");
	if (pos != dict.end())
	{
		dict.erase(pos);
		cout << "删除成功" << endl;
	}

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

运行结果

在这里插入图片描述

(1)从 map 容器中移除一组元素([first, last))

void testmap()
{
	map<string, string> dict;

	// 用make_pair函数来构造键值对
	dict["sort"] = "排序";
	dict["up"] = "向上";;
	dict["left"] = "左边";
	dict["root"] = "根";

	auto pos = dict.find("root");
	if (pos != dict.end())
	{
		dict.erase(pos, dict.end()); // 删除从pos位置开始后面所有的元素
		cout << "删除成功" << endl;
	}

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

可以看到 root 后面的元素已经被删掉了。

在这里插入图片描述

🍅 swap

交换 map 容器中的元素

在这里插入图片描述

代码示例

void testmap()
{
	map<string, string> dict1;
	dict1["sort"] = "排序";
	dict1["up"] = "向上";;
	dict1["left"] = "左边";
	dict1["root"] = "根";

	map<string, string> dict2;
	dict2["size"] = "大小";
	dict2["erase"] = "删除";
	dict2["clear"] = "清除";
	dict2["insert"] = "插入";

	dict1.swap(dict2); // 交换两个对象中的元素

	for (auto e1 : dict1)
	{
		cout << e1.first << ":" << e1.second << endl;
	}
	cout << endl;

	for (auto e2 : dict2)
	{
		cout << e2.first << ":" << e2.second << endl;
	}
}

可以看到两个对象的元素已经被交换

在这里插入图片描述

🍅 empty

检测 map 中的元素是否为空,是返回 true,否则返回 false。

在这里插入图片描述

代码示例

void testmap()
{
	map<string, string> dict1;
	dict1["sort"] = "排序";
	dict1["up"] = "向上";
	dict1["left"] = "左边";
	dict1["root"] = "根";

	map<string, string> dict2;

	cout << dict1.empty() << endl; // 不为空,返回false

	cout << dict2.empty() << endl; // 为空,返回true
}

运行结果

在这里插入图片描述

🍅 size

返回 map 中有效元素的个数

在这里插入图片描述

代码示例

void testmap()
{
	map<string, string> dict;
	dict["sort"] = "排序";
	dict["up"] = "向上";
	dict["left"] = "左边";
	dict["root"] = "根";

	cout << dict.size() << endl;
}

运行结果

在这里插入图片描述

🍅 count

获取 map 容器中指定 k 值的元素个数

在这里插入图片描述

代码示例

void testmap()
{
	map<string, string> dict;
	dict["sort"] = "排序";
	dict["up"] = "向上";
	dict["left"] = "左边";
	dict["root"] = "根";

	cout << dict.count("root") << endl; // root的个数
	cout << dict.count("hello") << endl; // hello的个数
}

运行结果

在这里插入图片描述

这个接口对于 map 容器其实没有太大用处,因为 map 当中的每个键值 key 和值 value 都是唯一的。

🍑 总结

  1. map 中的的元素是键值对
  2. map 中的 key 是唯一的,并且不能修改
  3. 默认按照小于的方式对 key 进行比较
  4. map 中的元素如果用迭代器去遍历,可以得到一个有序的序列
  5. map 的底层为平衡搜索树(红黑树),查找效率比较高 O ( l o g N ) O(logN) O(logN)
  6. 支持 [] 操作符,operator[] 中实际进行插入查找。

2. multimap的介绍和使用

multimap 的介绍:

  • multimaps 是关联式容器,它按照特定的顺序,存储由 key 和 value 映射成的键值对 <key, value>,其中多个键值对之间的 key 是可以重复的。
  • 在 multimap 中,通常按照 key 排序和唯一地标识元素,而映射的 value 存储与 key 关联的内容。key 和 value的类型可能不同,通过 multimap 内部的成员类型 value_type 组合在一起,value_type 是组合 key 和 value 的键值对:typedef pair<const Key, T> value_type;
  • 在内部,multimap 中的元素总是按照其内部比较对象(类型为 Compare)所指示的特定严格弱排序标准对 key 进行排序的。
  • multimap 通过 key 访问单个元素的速度通常比 unordered_multimap 容器慢,但是使用迭代器直接遍历 multimap 中的元素可以得到关于 key 有序的序列。
  • multimap 在底层用二叉搜索树(红黑树)来实现。

注意:multimap 和 map 的唯一不同就是:map 中的 key 是唯一的,而 multimap 中 key 是可以重复的。

multimap 的模板参数列表如下:

在这里插入图片描述

🍑 multimap的使用

multimap 允许键值 key 冗余,即 multimap 容器当中存储的元素是可以重复的。

代码示例

void testmultimap()
{
	multimap<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("up", "向上"));
	dict.insert(make_pair("left", "左边"));
	dict.insert(make_pair("root", "根"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("root", "原因"));
	dict.insert(make_pair("hello", "您好"));

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

可以看到是存在多个相同元素的。

在这里插入图片描述

另外,它和 map 容器所提供的成员函数的接口都是基本一致的,所以就不全部列举了,只列举几个稍微有点小差别的函数接口。

🍅 find

在容器中搜索 val 元素,如果找到,则返回中序位置的第一个迭代器,否则返回 multimap::end 的迭代器。

在这里插入图片描述

代码示例

void testmultimap()
{
	multimap<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("up", "向上"));
	dict.insert(make_pair("left", "左边"));
	dict.insert(make_pair("root", "根"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("root", "原因"));
	dict.insert(make_pair("hello", "您好"));
	dict.insert(make_pair("root", "路径"));

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}

	auto pos = dict.find("root"); // 多个root的话,返回中序第一个root

	// 打印pos位置后面的所有元素
	while (pos != dict.end())
	{
		cout << pos->first << ":" << pos->second << endl;
		++pos;
	}
}

可以看到确实是从第一个 root 开始打印的

在这里插入图片描述

🍅 count

在容器中搜索键值等于 k 的元素,并返回匹配的个数。

在这里插入图片描述

代码示例

void testmultimap()
{
	multimap<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("up", "向上"));
	dict.insert(make_pair("left", "左边"));
	dict.insert(make_pair("root", "根"));
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("root", "原因"));
	dict.insert(make_pair("hello", "您好"));
	dict.insert(make_pair("root", "路径"));

	// 统计root的元素个数
	cout << dict.count("root") << endl;

	// 遍历
	for (auto e : dict)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

可以看到 root 出现了 3 次

在这里插入图片描述

🍑 总结

  1. multimap 中的 key 是可以重复的。
  2. multimap 中的元素默认将 key 按照小于来比较
  3. multimap中没有重载 operator[] 操作。
  4. 使用时与 map 包含的头文件相同。

3. 前K个高频单词

题目描述

在这里插入图片描述

解题思路

首先定义一个 countMap,用来统计每种单词出现的次数。

再使用一个 SortMap,按照单词出现次数 int 进行降序排列(multimap默认是按照从小到大进行排序,传了一个 greater 仿函数,就是按照从大到小进行排序)。

在这里插入图片描述

由于 map 的排序是稳定的,所以排序后如果不同的单词有相同出现频率,会自动按字典顺序排列,就不会改变相对位置。

代码实现

class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        // 把单词和出现的次数放进map中
        // string就是words 
        // int就是words出现的次数
        map<string, int> countMap; 
        for (auto& str : words)
        {
            countMap[str]++;
        }

        // 排序
        // multimap默认是升序,传了仿函数,对int排降序
        multimap<int, string, greater<int>> sortMap;
        for (auto& kv : countMap)
        {
            // 因为是对int排序,所以此时int就是key,而words就是value
            // 那么此时单词出现的次数就按照从高到低排好了
            sortMap.insert(make_pair(kv.second, kv.first));
        }

        vector<string> ret; // 用来存放单词
        multimap<int, string>::iterator it = sortMap.begin();
        for (size_t i = 0; i < k; ++i)
        {
            // sortMap里面的first存放的是次数,second才是单词
            // 然后把words尾插进vector里面
            ret.push_back(it->second); 
            ++it;
        }
        return ret; // 返回结果
    }
};

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

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

相关文章

共享—1658页《Java面试突击核心手册》几乎覆盖市面上所有面试考点

说快也快&#xff0c;说不快也不慢&#xff01; 年前&#xff0c;陆陆续续&#xff0c;好多大厂都在裁员&#xff1b; 年后&#xff0c;又有一大批程序员失业&#xff0c;找不到避风港&#xff1b; 这时候&#xff0c;就有人说了&#xff0c;为什么找工作这么难&#xff1f;…

堆排序的概念

文章目录一、堆&#xff08;Heap&#xff09;的基本概念1.1 引入二叉树的顺序存储二、建立大根堆三、基于大根堆进行排序选择排序&#xff1a;在每一趟待排元素中选取关键字最小&#xff08;或最大&#xff09;的元素加入有序子序列选择排序分为&#xff1a; 简单选择排序堆排…

springboot+mybatis连接数据库实现增删改查功能

springbootmybatis连接数据库实现增删改查功能创建表创建项目实体类DAO接口写sql的XML文件Service层Controller启动类结果目录结构参考博客创建表 create table user(id int ,name varchar(30),pwd varchar(40) )insert into user values(2,hxf,789101),(3,hlm,789102),(4,hzh…

【ArcGIS自定义脚本工具】批量对栅格执行栅格计算器

文章目录一、功能介绍二、脚本代码三、工具参数四、用例4.1 批量单位换算4.2 批量计算植被覆盖度4.3 批量填充空值系列文章目录&#xff1a; ArcGIS自定义脚本工具一、功能介绍 功能 将多个栅格文件按照某以代数表达式执行栅格计算器(Raster Calculator) 工具&#xff0c;并将输…

linux内核内存笔记

一、linux用户态内核态内存结构 对于32位的linux操作系统&#xff0c;系统为每个进程分配0~4G的内存空间&#xff0c;而64位系统则更大&#xff1a; linux内存空间地址范围 可见Linux的内存分配规则&#xff1a; 二、总体分配规则 1、用户态在低地址&#xff0c;内核态在高地址…

进击中的 Zebec 生态,Web2 与 Web3 世界的连接器

虽然从意识形态上看&#xff0c;Web2世界与Web3世界存在着不同的逻辑&#xff0c;但我们同样看到&#xff0c;随着加密资产领域的发展&#xff0c;其正在作为优质投资品&#xff0c;被以Paypal、高盛等主流机构重视与接受。当然&#xff0c;除了作为投资者品外&#xff0c;近年…

C++学习笔记-环境设置

C 是一种通用编程语言&#xff0c;如今已广泛用于竞争性编程。它具有命令式&#xff0c;面向对象和通用编程功能。 C 在Windows&#xff0c;Linux&#xff0c;Unix&#xff0c;Mac等许多平台上运行。在开始使用C 进行编程之前。我们将需要在本地计算机上设置一个环境&#xff0…

用PHP实现CSPRepor报告预警信息存储和动态显示。

一、了解CSP内容安全策略 CSP 的实质就是白名单制度&#xff0c;开发者明确告诉客户端&#xff0c;哪些外部资源可以加载和执行&#xff0c;等同于提供白名单。它的实现和执行全部由浏览器完成&#xff0c;开发者只需提供配置。 作用就是&#xff1a;大大增强了网页的安全性。…

透明和半透明效果

Alpha通道 透明度可以通过base map的alpha通道来控制。Alpha值低的话&#xff0c;mesh就变得更加透明&#xff0c;alpha值高的话&#xff0c;mesh的透明度会变低&#xff0c;变得能更加轻松地被看到。当alpha为0时&#xff0c;mesh就完全不可见了&#xff0c;alpha值在中间时&a…

kubernetes(k8s) 知识总结(第2期)

1. “控制器”思想 kube-controller-manager 是一系列控制器的集合&#xff0c;这些控制器被放在 Kubernetes 项目的 pkg/controller 目录&#xff0c;这些控制器都以独有的方式负责某种编排功能。它们都遵循一个通用的编排模式——控制循环。 以 Deployment 为例介绍它对控…

最最普通程序员,如何利用工资攒够彩礼,成为人生赢家

今天我们不讲如何提升你的专业技能去涨工资&#xff0c;不讲面试技巧如何跳槽涨工资&#xff0c;不讲如何干兼职赚人生第一桶金&#xff0c;就讲一个最最普通的程序员&#xff0c;如何在工作几年后&#xff0c;可以攒够彩礼钱&#xff0c;婚礼酒席钱&#xff0c;在自己人生大事…

什么是网络流量分析(NTA),有什么好用的NTA软件

分析网络的稳定性首先要监控其性能、设备功能、网络速度以及许多网络管理员忽略的另一个方面&#xff1a;网络流量。网络流量分析 &#xff08;NTA&#xff09; 通常是考虑最少的方面&#xff0c;但它会影响许多问题&#xff0c;例如性能下降和用户速度缓慢。忽视它可能会让位于…

SQL语句实现找到一行中数据最大值(greatest)/最小值(least);mysql行转列

今日我在刷题时遇到这样一个题&#xff0c;它提到了以下需求&#xff1a; 有一场节目表演&#xff0c;五名裁判会对节目提供1-10分的打分&#xff0c;节目最终得分为去掉一个最高分和一个最低分后的平均分。 存在以下一张表performence_detail&#xff0c;包含字段有performa…

Docker安装RocketMQ 4.8

1拉取4.8镜像 docker pull foxiswho/rocketmq:4.8.0拉取控制台镜像 docker pull styletang/rocketmq-console-ng2创建rocketmq使用的共有网络&#xff0c;便于相互访问 docker network create rocketmq_network3启动rmqnamesrv docker run -d --name rmqnamesrv --network …

电脑录屏怎样不录到外界声音?调整这一个开关,即可实现

​有很多小伙伴希望自己电脑录屏的时候&#xff0c;不要录制自己的声音&#xff0c;而是通过后期配音的方式完成视频创作。电脑录屏怎样不录到外界声音&#xff1f;其实只需要调整这一个开关&#xff0c;就能实现不录外界声音&#xff0c;一起来看看吧。 不录外界声音1&#xf…

什么是 Java 泛型?

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注&#xff01; 作者| 慕课网精英讲师 ColorfulC 通过本篇文章你将了解到什么是泛型&#xff0c;为什么需要泛型&#xff0c;如何使用泛型&#xff0c;如何自定义泛型&…

记一次以小勃大,紧张刺激的渗透测试(2017年老文)

零、前言 有技术交流或渗透测试培训需求的朋友欢迎联系QQ/VX-547006660&#xff0c;需要代码审计、渗透测试、红蓝对抗网络安全相关业务可以看置顶博文 2000人网络安全交流群&#xff0c;欢迎大佬们来玩 群号820783253 一、起因 emmm&#xff0c;炎炎夏日到来&#xff0c;这…

libxlsxwriter数据验证

今天要分享的这个问题其实也属于excel的高级用法。我们想通过libxlsxwriter来实现一个能对用户的输入进行数据验证的表格功能。 内心os&#xff1a;小白最近是不是有点走火入魔了……我们真的会遇上这样的场景吗&#xff1a;需要通过代码生成一个表格&#xff0c;这个表格中还有…

智慧机场,或将成为航空领域数字孪生技术得完美应用

在《智慧民航建设路线图》文件中&#xff0c;民航局明确指出&#xff0c;智慧机场是实现智慧民航的四个核心抓手之一。这一战略性举措旨在推进数字化技术与航空产业的深度融合&#xff0c;为旅客提供更加智能化、便捷化、安全化的出行服务&#xff0c;进一步提升我国民航发展的…

IO流进阶

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录IO流进阶缓冲流缓冲流概述字节缓冲流(…