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

代码随想录算法训练营day6 | 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1.两数之和

文章目录

    • 哈希表
    • 哈希函数
    • 哈希冲突
      • 拉链法
      • 线性探测法
    • 常见的三种哈希结构
      • 集合
      • 映射
      • C++实现
        • std::unordered_set
        • std::map
    • 小结
    • 242.有效的字母异位词
      • 思路
      • 复习
    • 349. 两个数组的交集
      • 使用数组实现哈希表的情况
      • 思路
      • 使用set实现哈希表的情况
    • 202. 快乐数
      • 思路
    • 1.两数之和
      • 思路
    • 总结

今天是哈希表专题的第一天

Q:什么时候要用到哈希法?

A当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法

哈希表

哈希表 是一种通过哈希函数将键映射到表中位置的数据结构

哈希表的一些基本定义:

定义

  • 键是用来唯一标识哈希表中每个元素的部分。每个键在哈希表中必须是唯一的,即同一个哈希表中不能有两个相同的键。

作用

  • 定位:哈希表使用哈希函数将键转换为哈希值,然后用这个哈希值来决定元素存储的位置(桶/槽)。通过键可以高效地查找、插入或删除对应的元素。
  • 冲突解决:如果不同的键映射到同一个位置(即发生冲突),哈希表会使用冲突解决机制(如链表法或开放寻址法)来处理这些冲突。

例子

在一个学生成绩管理系统中,学生的学号可以作为键,用来唯一标识每个学生的成绩记录

定义

  • 值是与每个键关联的数据部分。每个键都对应一个值,值是存储在哈希表中的具体数据。

作用

  • 存储信息:值部分包含了与键相关的实际信息或数据。在哈希表中,通过键可以访问到对应的值。
  • 数据访问:当需要查询或操作数据时,通过键可以快速获取到相关的值。

例子

  • 在上述学生成绩管理系统中,学生的成绩可以作为值,存储在与学号关联的哈希表条目中。

实际上,数组就是一张哈希表:数组中的元素是键,它们被存放到数组的不同位置,在数组中可以通过下标直接访问数组中的元素,因此数组是一张哈希表

哈希表1

举个例子,如果想查询一个名字是否在这所学校里,如果使用枚举的话,时间复杂度是O(n);如果使用哈希表的话,只需要O(1)就能做到

如果使用哈希表存储和查找学生姓名,则在存储信息时把这所学校里学生的名字都存在哈希表里,在查询时通过索引直接就可以知道这位同学在不在这所学校里了

那么如何构建哈希表呢?这就涉及到了哈希函数,哈希函数将映射到哈希表中的某个位置

哈希函数

还是以“查询一个名字是否在这所学校里”为例,哈希函数将学生的姓名直接映射为哈希表上的索引。通过查询索引下标,我们能快速知道这位同学是否在这所学校里了

哈希函数的设计是哈希表的关键,在存储时,可能出现多个键对应同一个位置,这些键存储在哈希表的同一个位置处,这就是哈希冲突。如果哈希函数设计的不好,则会出现大量的哈希冲突

哈希函数如下图所示,hashCode使用特定的编码方式,把名字转化为数值,这样就把学生名字映射为哈希表上的索引数字了。由于哈希表的大小限制,为了保证映射出的索引数值都落在哈希表上,我们需要对hadhCode(name)取模,这保证了学生姓名一定可以映射到哈希表上

即使哈希函数计算的再均匀,也避免不了会有几位学生的名字同时映射到哈希表中同一个索引下标的位置。我们只能尽量寻找一个计算均匀的哈希函数,避免大量的哈希冲突

哈希表2

哈希冲突

下图展示的就是哈希冲突

哈希表3

如图,小李和小王都映射到了索引下标1的位置,这种现象就是哈希冲突

遇到哈希冲突有两种解决的思路:

  • 既然一个位置存不了多个键,那么就在这个位置后面做扩充。具体来说,哈希表的每个位置都指向一个链表的头节点,如果一个键对应到某个位置,则在该位置的链表末尾增加一个节点来存储这个键
  • 如果不想做扩展,那么我们就把键放到它对应位置附近的地方。具体来说,当发生冲突时,从冲突位置的下一个位置起,依次寻找空的散列地址,然后把这个键放到这个地址处

上面的两种思路对应哈希冲突的两种解决方案:拉链法 和 线性探测法

拉链法

思想:将所有哈希地址相同的记录存储在一个单链表中,在哈希表中存储的是所有子表的头指针

举例

哈希表4

小李和小王在索引1的位置处发生了冲突,发生冲突的元素都被存储在索引1的链表中,这样就可以通过索引查找到小李和小王了

注意:拉链法需要选择适当的哈希表大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间

线性探测法

思想:依靠哈希表中的空位来解决冲突。有多种探测空位的方法,这里介绍线性探测方法:当发生冲突时,从冲突位置的下一个位置起,依次寻找空的散列地址,然后把这个键放到这个地址处

为了能容纳所有的数据,一定要保证 哈希表大小 > 数据个数

举例

同样处理这个冲突,我们从索引1的下一个位置处起,寻找空的哈希位置。索引2的位置是空的,我们可以将小王存放到索引2的位置

哈希表5

常见的三种哈希结构

C++中是怎么使用哈希法解决问题呢?当使用哈希表时,我们一般会选择如下三种数据结构:

  • 数组
  • set(集合)
  • map(映射)

这三种结构的使用方式是依靠键(key)来访问值(value),所以使用这些数据结构来解决映射问题的方法叫作哈希法

集合

集合底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
std::set红黑树有序O(log n)O(log n)
std::multiset红黑树有序O(logn)O(logn)
std::unordered_set哈希表无序O(1)O(1)

红黑树是一种平衡二叉树,所以std::set和std::multiset的键值是有序的。但是键不可以修改,改动键的值会导致整棵树的错乱,所以只能删除和增加

当使用集合解决哈希问题时,优先使用undordered_set,它的查询和增删效率是最优的。如果集合是有序的,那么就用set。如果要求不仅有序还要有重复数据的话,那么就使用multiset

注意

  • **集合中的键值概念与其他数据结构(如映射或字典)中的有所不同。**集合中的每个元素都是一个唯一的“键”。在集合中,元素没有“值”这个概念,因为集合的主要目的是确保元素的唯一性和支持高效的集合操作(如插入、查找和删除),因此键即为值。集合只关心元素的存在性,不关心元素的附加数据或额外信息。

  • 虽然std::set和std::multiset 的底层实现基于红黑树而非哈希表,它们通过红黑树来索引和存储数据。不过给我们的使用方式,还是哈希法的使用方式,即依靠键(key)来访问值(value)。所以使用这些数据结构来解决映射问题的方法,我们依然称之为哈希法。std:map同理

映射

映射底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
std::map红黑树key有序key不可重复key不可修改O(logn)O(logn)
std::multimap红黑树key有序key可重复key不可修改O(log n)O(log n)
std::unordered_map哈希表key无序key不可重复key不可修改O(1)O(1)

同理,std::map和std::multimap的key值也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解——Carl)

注意:在map数据结构中,只对键有特定的要求和限制,而对值则没有限制:

  • 键是可比较的,以便能在红黑树中进行排序和查找操作,键必须能实现某种比较接口(例如在 C++ 中,键类型需要实现 < 运算符;在 Java 中,键类型需要实现 Comparable 接口)
  • 键是不可重复的(std::map、std::unordered_map)
  • 键是不可修改的,否则会扰乱红黑树的平衡结构(std::map、std::multimap)或者 会破坏哈希表的数据结构和性能(std::unordered_map)

值可以是任何数据类型,没有必须实现特定接口或运算符的要求。因为在map中,值只是与对应的键一起存储,不参与树结构的比较和排序操作

举例

#include <iostream>
#include <map>int main() {std::map<int, std::string> myMap;// 插入键值对myMap[1] = "one";myMap[2] = "two";myMap[3] = "three";// 打印 map 中的所有元素for (const auto& pair : myMap) {std::cout << pair.first << ": " << pair.second << std::endl;}return 0;
}

在这个例子中:

  • 键是整数类型,必须能够进行比较操作(红黑树需要对键进行排序和查找)
  • 值是字符串类型,可以是任意数据类型(没有特定要求)

C++实现

上面给出了C++标准库的集合和映射的实现方法。除此之外,还有hash_set hash_map,它们是由民间高手自发造的轮子(C++11标准之前造的)。实际上,hash_set hash_map与unordered_set,unordered_map的功能是一样的,但是unordered_set在C++11的时候被引入标准库了,而hash_set并没有,所以建议还是使用unordered_set比较好

哈希表6

std::unordered_set

特点

  • 元素无序
  • 插入、删除和查找操作的平均时间复杂度为 O(1)
  • 元素唯一
#include <iostream>
#include <unordered_set>int main() {std::unordered_set<int> mySet;// 插入元素mySet.insert(5);mySet.insert(3);mySet.insert(8);mySet.insert(1);// 打印集合中的元素for (const int& elem : mySet) {std::cout << elem << " ";}std::cout << std::endl;// 查找元素auto it = mySet.find(3);if (it != mySet.end()) {std::cout << "Element found: " << *it << std::endl;} else {std::cout << "Element not found" << std::endl;}return 0;
}
std::map

特点

  • 键自动排序
  • 插入、删除和查找操作的时间复杂度为 O(log⁡n)
  • 键唯一,值可重复
#include <iostream>
#include <map>int main() {std::map<int, std::string> myMap;// 插入键值对myMap[1] = "one";myMap[2] = "two";myMap[3] = "three";// pair函数构造键值对,存储到map容器中myMap.insert(std::pair<int, std::string>(4, "four"));// 打印键值对for (const auto& pair : myMap) {std::cout << pair.first << ": " << pair.second << std::endl;}// 查找键// find函数返回一个迭代器,指向包含指定键的元素,返回类型是 std::map<Key, T>::iteratorauto it = myMap.find(2);if (it != myMap.end()) {std::cout << "Found: " << it->first << " -> " << it->second << std::endl;} else {std::cout << "Not found" << std::endl;}return 0;
}

小结

直接贴上Carl的总结

当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

如果在做面试题目的时候遇到需要判断一个元素是否出现过的场景也应该第一时间想到哈希法!

今天的四道题很好,覆盖了三种哈希结构:数组、集合、映射

242.有效的字母异位词

题目链接:242. 有效的字母异位词 - 力扣(LeetCode)

这道题使用数组作为哈希表,数组作为哈希表在遍历上很方便

思路

数组其实就是一个简单哈希表,既然题目中字符串只有小写字符,那么就定义一个大小为26的数组record,用来统计字符串s、t中各种字符出现的次数。哈希函数:hash(key) = key-'a'

首先使用record统计字符串s中的各个字符:遍历字符串s,根据哈希函数,令record[key-‘a’]++

然后再统计字符串t中的各个字符。可以使用一个新的数组来统计,也可以使用原数组,我们使用原数组:遍历字符串t,根据哈希函数,令record[key-‘a’]–

经过上述统计,如果字符串s和字符串t是异位词,那么record数组的所有元素都应该为0。record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false

242.有效的字母异位词

代码实现

class Solution {
public:bool isAnagram(string s, string t) {// 统计两个字符串中各个字符出现的次数,依次比较即可// 设计hash函数为key-'a',哈希表(数组)大小为0~25std::vector<int> record(26, 0);for(char c : s){record[c-'a']++;}for(char c : t){record[c-'a']--;}// 检查record中的所有元素for(int count : record){if(count != 0){return false;}}return true;}
};
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

这道题的思路很简单,主要复习一下字符串的遍历和数组的定义

复习

数组定义和操作

C++中,std::vector<int> 可以用来定义一个动态数组

#include<iostream>
#include<vector>
int main()
{// 1.数组的定义std::vector<int> array1;	// 定义一个空的vectorstd::vector<int> array2 = {10, 20, 30, 40, 50};	// 使用初始值列表初始化vectorstd::vector<int> array3(5, 0);	// 定义一个大小为5的vector,所有元素初始化为0std::vector<int> array4(array3.begin(), array3,end());	//	范围构造函数,用array3创建array4// 2.访问和修改元素std::vector<int> myVector = {1, 2, 3, 4, 5};// 访问元素std::cout << "Element at index 2: " << myVector[2] << std::endl;// 修改元素myVector[2] = 10;std::cout << "Element at index 2 after modification: " << myVector[2] << std::endl;// 3.增加和删除元素(都是在末尾增删)// 添加元素myVector.push_back(4);myVector.push_back(5);// 移除最后一个元素myVector.pop_back();// 4.删除所有等于val的元素// 使用 std::remove 移动所有等于 val 的元素到末尾,返回指向移除操作后容器的逻辑末尾(不含所有val元素的容器末尾)auto new_end = std::remove(vec.begin(), vec.end(), val);// 使用 vector::erase 移除这些元素vec.erase(new_end, vec.end());// 5.删除第index位的元素if (index < vec.size()) {// 使用 vector::erase 删除第 index 位的元素vec.erase(vec.begin() + index);} else {std::cout << "Index out of bounds." << std::endl;}// 6.使用迭代器遍历 vectorfor (std::vector<int>::iterator it = myVector.begin(); it != myVector.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;return 0;
}

范围for循环

C++11引入了范围for循环,用于遍历容器,基本语法:

for (declaration : expression) {// loop body
}
  • declaration:声明一个变量,这个变量在每次迭代中都会被赋值为当前元素。

  • expression:一个表达式,返回一个可迭代的范围,例如数组、容器(如 std::vector)、初始化列表等。

for(int count : array)
{// loop body···
}

相当于

for(int i=0; i<arrat.size(); ++i)
{count = array[i];// loop body···
}

349. 两个数组的交集

Carl建议:本题就开始考虑 什么时候用set 什么时候用数组,本题其实是使用set的好题,但是后来力扣改了题目描述和 测试用例,添加了 0 <= nums1[i], nums2[i] <= 1000 条件,所以使用数组也可以了,不过建议大家忽略这个条件。 尝试去使用set

题目链接:349. 两个数组的交集 - 力扣(LeetCode)

这道题目用集合作为哈希表,集合能对元素做去重,而元素是无序的

使用数组实现哈希表的情况

这道题可以使用数组吗?不可以,使用数组来做哈希的题目,是因为题目都限制了数值的大小,比如上一道题限制字符串中都是小写字母,key只有26种,而本题没有限制数值的大小,就无法使用数组做哈希表了。而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费

思路

题目说明:输出结果中的每个元素一定是唯一的,也就是说输出的结果的去重的, 同时可以不考虑输出结果的顺序

如果使用集合,C++提供了三种可用的数据结构:

  • std::set
  • std::multiset
  • std::unordered_set

我们该选择哪一个?

std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希表, 使用unordered_set 读写效率是最高的,并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set

set哈希法

代码实现

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {std::unordered_set<int> result_set; // 存放结果,定义为set是为了去重for(int num : nums2){// 使用std::find函数在nums1中查找numif(find(num1.begin(), nums1.end(), num) != nums1.end()){result_set.insert(num);}}return vector<int>(result_set.begin(), result_set.end());}
};

std::find是C++标准库中的一个通用查找算法,用于在给定范围内查找指定元素。它接受两个迭代器作为参数,分别表示搜索范围的起始和结束位置。如果找到指定元素,则返回指向该元素的迭代器;否则,返回指向搜索范围末尾的迭代器。可以用于查找数组的元素 或 链表的节点

我们也可以先对其中一个数组进行去重,然后再求交集

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {std::unordered_set<int> result_set;	// 存放结果,定义为set是为了去重std::unordered_set<int> num_set(nums1.begin(), nums1.end());	// 先对nums1做去重for(int num : nums2){if(num_set.find(num) != num_set.end()){result_set.insert(num);}}return vector<int>(result_set.begin(), result_set.end());}
};
  • 时间复杂度: O(n + m) m 是最后要把 set转成vector
  • 空间复杂度: O(n)

使用set实现哈希表的情况

那有同学可能问了,遇到哈希问题我直接都用set不就得了,用什么数组啊。

直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。

不要小瞧 这个耗时,在数据量大的情况,差距是很明显的

202. 快乐数

建议:这道题目也是set的应用,其实和上一题差不多,就是 套在快乐数一个壳子

题目链接:202. 快乐数 - 力扣(LeetCode)

本题使用集合作为哈希表

思路

这道题的难点在如何判断是否进入了无限循环,出现无限循环一定是因为sum重复出现了。我们可以通过判断sum是否重复,进而判断是否进入了无限循环

当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了

所以这道题目使用哈希法,来判断sum是否重复出现

除此之外,本题还有一个难点:需要对数值各位做取数操作

代码实现

class Solution {
public:int getSum(int n){int sum = 0;while(n != 0){sum += (n % 10) * (n % 10);n /= 10;}return sum;}bool isHappy(int n) {unordered_set<int> set;while(1){int sum = getSum(n);    // 各位求和if(sum == 1){return true;}// 检查sum是否曾经出现过,如果出现过,则陷入了死循环if(set.find(sum) != set.end()){return false;}else{set.insert(sum);}n = sum;    // 进行下一轮循环}}
};

1.两数之和

建议:本题虽然是 力扣第一题,但是还是挺难的,也是 代码随想录中 数组,set之后,使用map解决哈希问题的第一题。

题目链接:1. 两数之和 - 力扣(LeetCode)

本题使用map作为哈希表

思路

  • 为什么会想到用哈希法?

    当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。

    这道题只需要遍历一趟数组,需要用一个集合记录我们遍历过的元素。定义:若元素1+元素2=target,则称元素1与元素2相匹配。当我们遍历到一个元素a时,我们查询集合中是否有与该元素a相匹配的元素b。这符合哈希法的使用原则:需要查询一个元素是否出现过,或者一个元素是否在集合里

  • 哈希表为什么用map

    • 数组作为哈希表的局限:数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。

    • set集合作为哈希表的局限:set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用

    • 使用map作为哈希表的原因:本题不仅需要知道元素是否遍历过,还要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适

    那么我们该选择哪种类型的map?

    映射底层实现是否有序数值是否可以重复能否更改数值查询效率增删效率
    std::map红黑树key有序key不可重复key不可修改O(log n)O(log n)
    std::multimap红黑树key有序key可重复key不可修改O(log n)O(log n)
    std::unordered_map哈希表key无序key不可重复key不可修改O(1)O(1)

    **本题不需要key有序,选择std::unordered_map效率更高!**因此选择std::unordered_map实现map

  • map用来做什么

    在遍历数组的过程中,map需要记录我们访问过的元素的值和对应的下标,这样才能找到与当前元素a相匹配的元素b,并获得元素b的下标

  • map中key和value分别表示什么

    map使用key寻找value。在数组的遍历过程中,我们需要判断 与当前元素a相匹配的 元素b是否出现过,即b=taregt-a是否在集合中。若元素b出现过,则返回元素b的下标。我们使用元素b的值寻找元素b的下标,因此map的存储结构为:

    • key:数组元素值
    • value:数组元素对应的下标
  • 整体思路

    遍历数组时,只需要在map中查询是否有和当前遍历到的元素a相匹配的元素b,具体来说,为auto it = map.find(target-a)

    • 如果元素b在map中,即it != map.end(),则找到了对应的匹配对,返回元素a、b的下标{i, it.second}
    • 如果没有找到元素b,则需要把当前遍历的元素a存放到map中,即map.insert(pair<int, int>(a, i)),这样map存放的就是我们访问过的元素,然后继续遍历数组

    过程如下:

    过程一

    过程二

代码实现

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {// 返回匹配上的两个元素的下标// 定义一个map,用来存放在数组遍历过程中,见过的所有元素// 然后每次遍历到一个新的元素时,都查询traget-该元素 是否在map中// 如果在map中,则返回;否则,将该元素直接加入到map中std::unordered_map<int, int> map;for(int i=0; i<nums.size(); ++i){auto it = map.find(target-nums[i]);if(it != map.end()){return {it->second, i};}else{map.insert(pair<int, int>(nums[i], i));}}return {};}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

总结

今天是哈希表专题的第一天,复习了哈希表的基本知识,学习了哈希法的思想:当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。学习了 数组、集合、映射实现哈希表的方法和基本操作,以及C++中如何实现这些数据结构。今天的四道题覆盖了这三种哈希结构,可以总结一下三种结构的优缺点:

  • 数组:

    • 优点:数组作为哈希表在遍历上很方便
    • 缺点:数组的大小是受限制的,所以要处理的数据是有大小限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
  • 集合:

    • 优点:集合能对元素做去重,当需要对数据进行去重处理时,可以考虑使用集合。集合对处理的数据没有大小限制

    • 缺点:set是一个集合,里面放的元素只能是一个key。实际上,集合没有“值”的概念,或者说 键就是值。因此想要存放一些与键相关的信息,就不能使用集合。另外,直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。

      不要小瞧 这个耗时,在数据量大的情况,差距是很明显的

  • 映射:

    • 优点:映射对数据大小没有限制,如果想要存放与键相关的信息,就需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适
    • 缺点:内存开销大。由于维护树结构或哈希表的开销,映射在某些操作上(如遍历、批量插入)比数组和集合慢

除此之外,还复习了迭代器、范围for循环、vector容器的操作,std::find函数 和 std::pair函数

第三、四道题一开始看不出要使用哈希法,我们将问题分析后转化,发现需要查找元素是否在集合中,适合哈希法的使用情况,因此使用哈希法,然后进一步分析使用哪种结构(数组、集合、映射)实现哈希表。这种分析问题,转化问题的能力很重要

相关文章:

代码随想录算法训练营day6 | 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1.两数之和

文章目录 哈希表键值 哈希函数哈希冲突拉链法线性探测法 常见的三种哈希结构集合映射C实现std::unordered_setstd::map 小结242.有效的字母异位词思路复习 349. 两个数组的交集使用数组实现哈希表的情况思路使用set实现哈希表的情况 202. 快乐数思路 1.两数之和思路 总结 今天是…...

vue3 vxe-table 点击行,不显示选中状态,加上设置isCurrent: true就可以设置选中行的状态。

1、上个图&#xff0c;要实现这样的&#xff1a; Vxe Table v4.6 官方文档 2、使用 row-config.isCurrent 显示高亮行&#xff0c;当前行是唯一的&#xff1b;用户操作点击选项时会触发事件 current-change <template><div><p><vxe-button click"sel…...

Linux没有telnet 如何测试对端的端口状态

前段时间有人问uos没有telnet&#xff0c;又找不到包。 追问了一下为什么非要安装telnet&#xff0c;答复是要测试对端的端口号。 这里简单介绍一下&#xff0c;测试端口号的方法有很多&#xff0c;telent只是在windows上经常使用&#xff0c;linux已很少安装并使用该命令&…...

花几千上万学习Java,真没必要!(二十九)

1、基本数据类型包装类&#xff1a; 测试代码1&#xff1a; package apitest.com; //使用Integer类的不同方法处理整数。 //将字符串转换为整数&#xff08;parseInt&#xff09;和Integer对象&#xff08;valueOf&#xff09;&#xff0c; //将整数转换回字符串&#xff08;…...

C#如何引用dll动态链接库文件的注释

1、dll动态库文件项目生成属性中要勾选“XML文档文件” 注意&#xff1a;XML文件的名字切勿修改。 2、添加引用时XML文件要与DLL文件在同一个目录下。 3、如果要是添加引用的时候XML不在相同目录下&#xff0c;之后又将XML文件复制到相同的目录下&#xff0c;需要删除引用&am…...

WordPress原创插件:自定义文章标题颜色

插件设置截图 文章编辑时&#xff0c;右边会出现一个标题颜色设置&#xff0c;可以设置为任何颜色 更新记录&#xff1a;从输入颜色css代码&#xff0c;改为颜色选择器&#xff0c;更方便&#xff01; 插件免费下载 https://download.csdn.net/download/huayula/89585192…...

Unity分享:继承自MonoBehaviour的脚步不要对引用类型的字段在声明时就初始化

如果某些字段在每个构造函数中都要进行初始化&#xff0c;很多人都喜欢在字段声明时就进行初始化&#xff0c;对于一个非继承自MonoBehaviour的脚步&#xff0c;这样做是没有问题的&#xff0c;然而继承自MonoBehaviour后就会造成内存的浪费&#xff0c;为什么呢&#xff1f;因…...

.NET Core中如何集成RabbitMQ

在.NET Core中集成RabbitMQ主要涉及到几个步骤&#xff0c;包括安装RabbitMQ的NuGet包、建立连接、定义队列、发送和接收消息等。下面是一个简单的指南来展示如何在.NET Core应用程序中集成RabbitMQ。 目录 1. 安装RabbitMQ.Client NuGet包 2. 建立连接 3. 定义队列 4. 发…...

嵌入式C++、STM32、MySQL、GPS、InfluxDB和MQTT协议数据可视化:智能物流管理系统设计思路流程(附代码示例)

目录 项目概述 系统设计 硬件设计 软件设计 系统架构图 代码实现 1. STM32微控制器与传感器代码 代码讲解 2. MQTT Broker设置 3. 数据接收与处理 代码讲解 4. 数据存储与分析 5. 数据分析与可视化 代码讲解 6. 数据可视化 项目总结 项目概述 随着电子商务的快…...

.net core docker部署教程和细节问题

在.NET Core中实现Docker一键部署&#xff0c;通常涉及以下几个步骤&#xff1a;编写Dockerfile以定义镜像构建过程、构建Docker镜像、运行Docker容器&#xff0c;以及&#xff08;可选地&#xff09;使用自动化工具如Docker Compose或CI/CD工具进行一键部署。以下是一个详细的…...

php数据库链接

Php超全局变量 GET 和 POST 都创建一个数组&#xff08;例如 array&#xff08; key1 > value1&#xff0c; key2 > value2&#xff0c; key3 > value3&#xff0c; ...&#xff09;&#xff09;。此数组包含键/值对&#xff0c;其中 键是表单控件的名称&#xff0c;…...

python+vue3+onlyoffice在线文档系统实战20240726笔记,左侧菜单实现和最近文档基本实现

解决右侧高度过高的问题 解决方案&#xff1a;去掉右侧顶部和底部。 实现左侧菜单 最近文档&#xff0c;纯粹文档 我的文档&#xff0c;既包括文件夹也包括文件 共享文档&#xff0c;别人分享给我的 基本实现代码&#xff1a; 渲染效果&#xff1a; 简单优化 设置默认菜…...

vue中的nexttrick

Vue.js 是一个用于构建用户界面的渐进式框架&#xff0c;它允许开发者通过声明式的数据绑定来构建网页应用。在 Vue 中&#xff0c;nextTick 是一个非常重要的 API&#xff0c;它用于延迟回调的执行&#xff0c;直到下次 DOM 更新循环之后。 为什么使用 nextTick&#xff1f; …...

【BUG】已解决:ModuleNotFoundError: No module named ‘requests‘

ModuleNotFoundError: No module named ‘requests‘ 目录 ModuleNotFoundError: No module named ‘requests‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&a…...

深入理解JS中的发布订阅模式和观察者模式

发布/订阅模式(Publish/Subscribe)和观察者模式(Observer Pattern)在概念上非常相似,都是用于实现对象之间的松耦合通信。尽管它们在实现细节和使用场景上有所不同,但核心思想是相通的。 观察者模式 直接通信:在观察者模式中,观察者(Observer)直接订阅主题(Subject…...

网站IPv6支持率怎么检测?

在当今数字化的时代&#xff0c;IPv6的推广和应用已经成为网络发展的重要趋势。IPv6拥有更大的地址空间、更高的安全性和更好的性能&#xff0c;对于满足日益增长的网络需求至关重要。对于网站所有者和管理员来说&#xff0c;了解其网站对IPv6的支持率是评估网站性能和兼容性的…...

react中简单的配置路由

1.安装react-router-dom npm install react-router-dom 2.新建文件 src下新建page文件夹&#xff0c;该文件夹下新建login和index文件夹用于存放登录页面和首页&#xff0c;再在对应文件夹下分别新建入口文件index.js&#xff1b; src下新建router文件用于存放路由配置文件…...

RocketMQ消息短暂而又精彩的一生(荣耀典藏版)

目录 前言 一、核心概念 二、消息诞生与发送 2.1.路由表 2.2.队列的选择 2.3.其它特殊情况处理 2.3.1.发送异常处理 2.3.2.消息过大的处理 三、消息存储 3.1.如何保证高性能读写 3.1.1.传统IO读写方式 3.2零拷贝 3.2.1.mmap() 3.2.2sendfile() 3.2.3.CommitLog …...

Linux中的文件操作

linux中exec*为加载器&#xff0c;可以将程序加载到内存。 main()函数也是函数&#xff0c;也要被调用&#xff0c;也要被传参 故在一个程序中exec*系列的函数先被执行 程序替换中execve是系统调用&#xff0c;其他的都是封装。 进程程序替换 1.创建子进程的目的&#xff1…...

[排序]hoare快速排序

今天我们继续来讲排序部分&#xff0c;顾名思义&#xff0c;快速排序是一种特别高效的排序方法&#xff0c;在C语言中qsort函数&#xff0c;底层便是用快排所实现的&#xff0c;快排适用于各个项目中&#xff0c;特别的实用&#xff0c;下面我们就由浅入深的全面刨析快速排序。…...

freertos的学习cubemx版

HAL 库的freertos 1 实时 2 任务->线程 3 移植 CMSIS_V2 V1版本 NVIC配置全部是抢占优先级 第四组 抢占级别有 0-15 编码规则&#xff0c; 变量名 &#xff1a;类型前缀&#xff0c; c - char S - int16_t L - int32_t U - unsigned Uc - uint8_t Us - uint…...

PyQt 信号与槽功能

PyQt 信号与槽功能 基本概念&#xff1a;在 PyQt 中&#xff0c;信号&#xff08;Signal&#xff09;与槽&#xff08;Slot&#xff09;是一种用于对象之间通信的机制。信号可以由一个对象发出&#xff0c;而槽是用于接收信号并执行相应操作的函数。 信号 信号是在 PyQt 的类…...

navicat premium安装和破解

https://blog.csdn.net/qq1031893936/article/details/90264688 提示信息 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn...

OSI七层模型

OSI&#xff08;Open System Interconnect&#xff09;&#xff0c;即开放式系统互连。 该体系结构标准定义了网络互连的七层框架&#xff08;物理层、数据链路层、网络层、传输层、会话层、表示层和应用层 &#xff09;&#xff0c;即OSI开放系统互连参考模型。 应用层 为用…...

Qt自定义MessageToast

效果&#xff1a; 文字长度自适应&#xff0c;自动居中到parent&#xff0c;会透明渐变消失。 CustomToast::MessageToast(QS("最多添加50张图片"),this);1. CustomToast.h #pragma once#include <QFrame>class CustomToast : public QFrame {Q_OBJECT pub…...

自动化测试 pytest 中 scope 限制 fixture使用范围!

导读 fixture 是 pytest 中一个非常重要的模块&#xff0c;可以让代码更加简洁。 fixture 的 autouse 为 True 可以自动化加载 fixture。 如果不想每条用例执行前都运行初始化方法(可能多个fixture)怎么办&#xff1f;可不可以只运行一次初始化方法&#xff1f; 答&#xf…...

软件-vscode-plantUML-drawio

文章目录 vscode基础命令 实操1. vscode实现springboot项目搭建 &#xff08;包括spring data jpa和sqlLite连接&#xff09; PlantUMLDrawio基础实操 vscode 基础 命令 启动mysql命令 docker run --name mysql-container -e MYSQL_ROOT_PASSWORD123456 -p 3306:3306 -d my…...

Python爬虫实战案例(爬取图片)

爬取图片的信息 爬取图片与爬取文本内容相似&#xff0c;只是需要加上图片的url&#xff0c;并且在查找图片位置的时候需要带上图片的属性。 这里选取了一个4K高清的壁纸网站&#xff08;彼岸壁纸https://pic.netbian.com&#xff09;进行爬取。 具体步骤如下&#xff1a; …...

智慧工地视频汇聚管理平台:打造现代化工程管理的全新视界

一、方案背景 科技高速发展的今天&#xff0c;工地施工已发生翻天覆地的变化&#xff0c;传统工地管理模式很容易造成工地管理混乱、安全事故、数据延迟等问题&#xff0c;人力资源的不足也进一步加剧了监管不到位的局面&#xff0c;严重影响了施工进度质量和安全。 视频监控…...

ASP.NET中的六大对象有哪些?以及各自的功能以及使用方式

在ASP.NET Web Forms中&#xff0c;并没有严格意义上的“六大对象”&#xff0c;但通常我们指的是与HTTP请求和响应处理紧密相关的几个内置对象。以下是这些对象及其功能、使用方式以及简单的实现源码示例&#xff1a; Response对象 功能&#xff1a;用于向客户端发送HTTP响应…...

Elastic 及阿里云 AI 搜索 Tech Day 将于 7 月 27 日在上海举办

活动主题 面向开发者的 AI 搜索相关技术分享&#xff0c;如 RAG、多模态搜索、向量检索等。 活动介绍 参加 Elastic 原厂与阿里云联合举办的 Generative AI 技术交流分享日。借助 The Elastic Search AI Platform&#xff0c; 使用开放且灵活的企业解决方案&#xff0c;以前所…...

基于ssm+vue医院住院管理系统源码数据库

摘 要 随着时代的发展&#xff0c;医疗设备愈来愈完善&#xff0c;医院也变成人们生活中必不可少的场所。如今&#xff0c;已经2021年了&#xff0c;虽然医院的数量和设备愈加完善&#xff0c;但是老龄人口也越来越多。在如此大的人口压力下&#xff0c;医院住院就变成了一个…...

【在排序数组中查找元素的第一个和最后一个位置】python刷题记录

R2-分治 有点easy的感觉&#xff0c;感觉能用哈希表 class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:nlen(nums)dictdefaultdict(list)#初始赋值哈希表&#xff0c;记录出现次数for num in nums:if not dict[num]:dict[num]1else:dict[…...

Pytorch基础:Tensor的squeeze和unsqueeze方法

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 在Pytorch中&#xff0c;squeeze和unsqueeze是Tensor的一个重要方法&#xff0c;同时它们也是torch模块中的一个函数&#xff0c;它们的语法如下所示。 Tensor.…...

PHP压缩打包,下载目录或者文件,解压zip文件

函数 /*** 压缩整个文件夹为zip文件* 本地需要绝对路径&#xff0c;服务器需要相对路径*/function makeZipFile($zip_path , $folder_path ) {$rootPath realpath($folder_path);$zip new ZipArchive(); // $zip->open($zip_path, ZipArchive::CREATE | ZipArchi…...

后端面试题日常练-day08 【Java基础】

题目 希望这些选择题能够帮助您进行后端面试的准备&#xff0c;答案在文末 Java中的静态变量和实例变量有何区别&#xff1f; a) 静态变量属于类&#xff0c;实例变量属于对象 b) 静态变量只能在静态方法中访问&#xff0c;实例变量只能在实例方法中访问 c) 静态变量在类加载时…...

Linux:core文件无法生成排查步骤

1、进程的RLIMIT_CORE或RLIMIT_SIZE被设置为0。使用getrlimit和ulimit检查修改。 使用ulimit -a 命令检查是否开启core文件生成限制 如果发现-c后面的结果是0&#xff0c;就临时添加环境变量ulimit -c unlimited&#xff0c;之后在启动程序观察是否有core生成&#xff0c;如果…...

大模型学习资源

上一篇扯了一堆废话&#xff0c;关于大模型&#xff0c;提供一下建议 说实话&#xff0c;大模型更新太快&#xff0c;以我30岁的高龄实在不适合再去研究技术。偶然发现&#xff0c;国内的大模型厂家在做推广的培训。比如上海人工智能实验室&#xff0c;阿里&#xff0c;百度。…...

约定(模拟赛2 T3)

题目描述 小A在你的帮助下成功打开了山洞中的机关&#xff0c;虽然他并没有找到五维空间&#xff0c;但他在山洞中发现了无尽的宝藏&#xff0c;这个消息很快就传了出去。人们为了争夺洞中的宝藏相互陷害&#xff0c;甚至引发了战争&#xff0c;世界都快要毁灭了。小A非常地难…...

Java推送xml数据进行http请求

将json转成xml数据进行推送&#xff0c;打印出最终推送xml的数据格式&#xff0c;再调整代码 直接上代码&#xff0c;详情请看代码注释 public void pushReceipt(JSONObject jsonObj) {try {// 创建 XML 文档Document doc createXmlDocument();// 构建 XML 结构Element rootE…...

Docker安装 OpenResty详细教程

OpenResty 是一个基于 Nginx 的高性能 Web 平台&#xff0c;它集成了 Lua 脚本语言&#xff0c;使得开发者可以在 Nginx 服务器上轻松地进行动态 Web 应用开发。OpenResty 的核心目标是通过将 Nginx 的高性能与 Lua 的灵活性结合起来&#xff0c;提供一个强大且高效的 Web 开发…...

前端位运算运用场景小知识(权限相关)

前提&#xff1a;此篇结合AI、公司实际业务产出&#xff0c;背景是公司有个业务涉及权限&#xff0c;用位运算来控制的&#xff0c;比较新奇&#xff0c;所以记录一下(可能自己比较low) 前端js位运算一般实际的应用场景在哪 ai回答&#xff1a; 整数运算与性能优化&#xff…...

【云原生】Kubernetes中的DaemonSet介绍、原理、用法及实战应用案例分析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

使用框架构建React Native应用程序的最佳实践

在React Conf上&#xff0c;我们更新了关于开始构建React Native应用程序的最佳工具的指导&#xff1a;一个React Native框架——一个包含所有必要API的工具箱&#xff0c;让您能够构建生产就绪的应用程序。 现在推荐使用React Native框架&#xff08;如Expo&#xff09;来创建…...

Godot入门 02玩家1.0版

添加Node2D节点&#xff0c;重命名Game 创建玩家场景&#xff0c;添加CharacterBody2D节点 添加AnimatedSprite2D节点 从精灵表中添加帧 选择文件 设置成8*8 图片边缘模糊改为清晰 设置加载后自动播放&#xff0c;动画循环 。动画速度10FPS&#xff0c;修改动画名称idle。 拖动…...

Docker-Compose配置zookeeper+KaFka+CMAK简单集群

1. 本地DNS解析管理 # 编辑hosts文件 sudo nano /etc/hosts # 添加以下三个主机IP 192.168.186.77 zoo1 k1 192.168.186.18 zoo2 k2 192.168.186.216 zoo3 k3注&#xff1a;zoo1是192.168.186.77的别名&#xff0c;zoo2是192.168.186.18的别名&#xff0c;zoo3是192.168.186.1…...

Python中,集合几种基本运算

在Python中&#xff0c;集合具有几种基本的集合运算&#xff0c;这些运算可以用于处理集合中的数据。以下是Python集合的常见运算&#xff0c;包括并集、交集、差集和对称差集等&#xff0c;并提供代码示例来显示其用法。 并集 (Union) 并集是两个集合中所有唯一元素的结合&a…...

netsuite查询货品库存

//单品可用数量获取var inventorySearch search.create({type: inventoryitem,filters: [[internalid, is, lineItem2.nsSkuId] // 根据 SKU ID 进行筛选],columns: [search.createColumn({name: locationquantityavailable,summary: SUM}) // 获取可用库存总和]});var result…...

Java 实现分页的几种方式详解

目录 分页概述Java实现分页的几种方式 手动分页基于JDBC的分页基于Hibernate的分页基于MyBatis的分页[基于Spring Data JPA的分页](#基于Spring Data JPA的分页)使用PageHelper插件的分页 分页中的注意事项总结 分页概述 分页是指将大量数据分成若干小块&#xff0c;每次只显…...

vite构建vue3项目hmr生效问题踩坑记录

vite构建vue3项目hmr生效问题踩坑记录 hmr的好处 以下是以表格形式呈现的前端开发中HMR&#xff08;热模块替换&#xff09;带来的好处&#xff1a; 好处描述提升开发效率允许开发者在不刷新整个页面的情况下实时更新修改的代码&#xff0c;减少等待时间保持应用状态在模块替…...