C++容器set和multiset使用详解

news2024/7/4 15:05:49

文章目录

      • 1.set和multiset容器
        • 1.基本特性
        • 2.multiset容器
        • 3.set的构造和赋值
          • 1.构造函数
          • 2.赋值操作
          • 3.注意事项
        • 4.set的大小和交换
          • 1.获取大小
          • 2.检查是否为空
          • 3.交换两个set
          • 4.示例综合
        • 5.set容器插入和删除
          • 1.插入元素
          • 2.删除元素
          • 3.示例
        • 6.set容器的查找和统计
          • 1.查找元素
          • 2.统计元素个数
          • 3.注意事项
        • 9.set和multiset的区别
        • 9.pair对组的创建
          • 1. 直接构造
          • 2. 使用make_pair函数
          • 3. 初始化列表
          • 4. 结构化绑定(C++17起)
          • 5.示例
        • 10.set内置数据类型排序
        • 11.set对自定义数据类型排序

1.set和multiset容器

C++的std::set容器是STL(标准模板库)中的一个关联容器,它用于存储唯一对象的集合。每个元素的位置都是由它的值决定的,这意味着std::set中的元素会自动排序。std::set底层通常通过红黑树实现,提供了对数时间复杂度的插入、删除和查找操作。

1.基本特性
  1. 有序性std::set中的元素默认按照升序排序。也可以通过传入自定义的比较函数来改变排序方式。
  2. 唯一性:不允许有重复的元素,根据元素的排序准则,如果有重复的元素尝试插入,它们会被自动忽略。
  3. 动态大小:容器的大小会根据需要自动调整。
  4. 迭代器:提供了向前和向后遍历的迭代器,但不支持随机访问迭代器,因为元素在内存中不是连续存储的。

常用操作

  • 构造

    std::set<int> mySet; // 创建一个空的int型set
    std::set<std::string, std::greater<std::string>> mySetStr; // 使用自定义排序(降序)
    
  • 插入

    mySet.insert(42); // 插入一个元素
    mySet.insert({1, 2, 3}); // 插入多个元素
    
  • 查找

    if (mySet.find(42) != mySet.end()) {
        std::cout << "Found 42 in set.\n";
    }
    
  • 删除

    mySet.erase(42); // 删除一个特定值的所有实例
    mySet.erase(it); // 删除迭代器it指向的元素
    mySet.clear(); // 清空整个集合
    
  • 检查存在性

    if (mySet.count(42)) {
        std::cout << "42 is in the set.\n";
    }
    
  • 大小与空判断

    std::cout << "Size: " << mySet.size() << "\n";
    if (mySet.empty()) {
        std::cout << "Set is empty.\n";
    }
    
  • 遍历

    for (const auto& elem : mySet) {
        std::cout << elem << " ";
    }
    

自定义比较函数

可以通过传递比较函数对象作为第二个模板参数来自定义元素的排序规则。例如,如果要创建一个按字符串长度排序的set,可以这样做:

struct CompareByLength {
    bool operator()(const std::string& s1, const std::string& s2) const {
        return s1.size() < s2.size();
    }
};

std::set<std::string, CompareByLength> mySetByLength;

总结

std::set容器非常适合需要维护唯一且有序数据集合的场景。它的主要优点在于自动排序和保证元素唯一性,但这也意味着插入和删除操作相比无序容器(如std::unordered_set)可能更耗时。选择使用std::set还是其他容器应基于具体的应用需求。

2.multiset容器

在C++的STL(标准模板库)中,std::setstd::multiset都是关联容器,主要用于存储元素的集合,它们的主要区别在于对元素唯一性的处理上:

std::set

  • 唯一性std::set不允许容器中有重复的元素。这意味着如果你尝试插入一个已经存在于set中的元素,插入操作将被忽略,容器不会发生任何变化。
  • 排序:所有元素都会在插入时自动被排序。排序是基于元素的比较操作符(默认为 < 运算符),或者你可以在创建set时提供一个自定义的比较函数。
  • 用途:适用于需要存储唯一且有序数据的场景,如索引、去重等。

std::multiset

  • 重复性:与std::set不同,std::multiset允许容器中有重复的元素。它可以存储多个具有相同值的元素,并且这些相同值的元素在multiset中的顺序取决于它们的插入顺序。
  • 排序:虽然允许重复,但元素仍然是排序的,同样基于比较操作符或自定义比较函数。
  • 用途:适合那些需要记录元素出现次数或者保持元素插入顺序的同时还需要维持元素排序的场景,如统计词频、事件日志等。

共同点

  • 底层结构:两者通常都采用红黑树实现,因此提供了对数时间复杂度的高效插入、删除和查找操作。
  • 迭代器:都提供了迭代器支持,可以用来遍历容器中的元素,但不支持随机访问迭代器,因为它们是基于节点的链式存储结构。
  • 动态大小:容器大小会根据元素的插入和删除动态调整。

应用决策

选择使用std::set还是std::multiset取决于你的具体需求:

  • 如果你的应用逻辑要求集合中的元素必须唯一,那么你应该使用std::set
  • 如果你需要保留重复元素并能对它们进行排序和计数,则std::multiset是更好的选择。
3.set的构造和赋值

std::set容器提供了多种构造方法和赋值操作。

1.构造函数
  1. 默认构造函数

    std::set<T> mySet; // T 是元素类型,例如 int, std::string 等
    

    创建一个空的set,元素类型为T,按照T的默认排序方式进行排序。

  2. 拷贝构造函数

    std::set<T> mySetCopy(mySet);
    

    创建一个新的set,它是已有setmySet)的一个拷贝。

  3. 带有比较函数的构造函数

    struct MyComparator {
        bool operator()(const T& lhs, const T& rhs) const { /* 自定义比较逻辑 */ }
    };
    std::set<T, MyComparator> mySetWithComparator;
    

    创建一个空的set,使用自定义的比较函数MyComparator

  4. 区间构造函数

    std::set<T> mySet(begin(iterable), end(iterable));
    

    从一个迭代器范围(如另一个容器或数组)构造set,只包含范围内唯一且排序后的元素。

  5. 初始化列表构造(C++11起):

    std::set<int> mySet = {1, 3, 2}; // 注意自动排序为{1, 2, 3}
    
2.赋值操作
  1. 拷贝赋值

    std::set<T> mySet;
    std::set<T> anotherSet;
    // ...填充anotherSet
    mySet = anotherSet; // mySet 现在是 anotherSet 的拷贝
    
  2. 区间赋值

    std::set<T> mySet;
    // ...填充mySet
    std::set<T> anotherSet;
    anotherSet.assign(begin(iterable), end(iterable)); // 用 iterable 中的元素替换 anotherSet 的内容
    
  3. 初始化列表赋值(C++11起):

    std::set<int> mySet = {4, 2, 5, 1}; // 初始化后自动排序为{1, 2, 4, 5}
    
3.注意事项
  • 在赋值和构造时,如果源集合中有重复元素(对于std::set而言,这是不可能的情况,因为std::set不允许重复),目标集合将只保留唯一的元素。
  • 所有这些操作都不会影响原集合的迭代器、引用和指针的有效性,除非进行的是自赋值操作(即将一个容器赋值给自己),此时容器保持不变。
  • 当涉及到大型集合时,上述操作的性能需考虑,尤其是拷贝构造和赋值可能会涉及大量元素的复制。C++11引入了右值引用和移动语义,可以更高效地处理这类情况。
// 包含标准输入输出库和集合库
#include <iostream>
#include <set>
using namespace std;

/**
 * 打印集合中的所有元素
 * @param S 需要打印的集合
 */
void printSet(const set<int>& S){
    // 遍历集合中的每个元素并打印
    for(auto &it : S){
        cout << it << " ";
    }
    cout << endl;
}

int main(){
    // 初始化一个集合S并填充元素
    set<int> S = {1,2,3,4};
    // 调用函数打印集合S
    printSet(S);
    
    // 引用集合S,创建常量引用S1
    const set<int>& S1(S);
    // 调用函数打印引用S1
    printSet(S1);
    
    // 初始化一个空集合S2
    set<int> S2;
    // 将集合S的值赋给集合S2
    S2 = S;
    // 调用函数打印集合S2
    printSet(S2);
    
    return 0;
}
4.set的大小和交换

在C++的std::set容器中,获取容器的大小以及交换两个容器的内容是常见的操作。

1.获取大小

使用size()成员函数可以获取std::set容器中当前元素的数量。

std::set<int> mySet = {1, 2, 3, 4, 5};
std::cout << "Size of mySet: " << mySet.size() << std::endl;
2.检查是否为空

使用empty()成员函数可以检查std::set容器是否为空。

if (mySet.empty()) {
    std::cout << "mySet is empty." << std::endl;
} else {
    std::cout << "mySet is not empty." << std::endl;
}
3.交换两个set

std::set提供了swap()成员函数,可以高效地交换两个集合的所有元素,不会抛出异常。

std::set<int> anotherSet = {6, 7, 8, 9, 10};
mySet.swap(anotherSet); // 交换mySet和anotherSet的内容
4.示例综合
// 包含标准输入输出库和集合库
#include <iostream>
#include <set>
// 使用标准命名空间,简化代码中标准库函数的调用
using namespace std;

/**
 * 打印集合中的所有元素
 * @param S 需要打印的集合,以引用传递,避免复制集合导致的性能损失
 */
void printSet(const set<int>& S){
    // 遍历集合中的每个元素,并打印它们
    for(auto &it : S){
        cout << it << " ";
    }
    // 换行,以便后续输出开始于新行
    cout << endl;
}

int main(){
    // 初始化一个集合S,包含整数5, 4, 6, 8, 9
    set<int>S = {5,4,6,8,9};
    // 调用函数打印集合S的内容
    printSet(S);
    // 输出集合S的元素数量
    cout << S.size() << endl;
    // 检查集合S是否为空,如果不为空,则再次打印集合S的内容
    if(!S.empty()){
        printSet(S);
    }
    // 初始化另一个空集合S1
    set<int>S1;
    // 交换集合S和S1的内容,将S的内容转移到S1中,S变为空集合
    S.swap(S1);
    // 分别打印交换后的集合S和S1的内容
    printSet(S);
    printSet(S1);
    return 0;
}

这段代码首先展示了如何获取两个集合的大小以及检查它们是否为空,然后使用swap()函数交换这两个集合的内容,并再次打印交换后的大小,展示了容器大小的查询和元素交换的基本操作。

5.set容器插入和删除

在C++的std::set容器中,插入和删除元素是非常基本且常用的操作。

1.插入元素
  1. 单个元素插入:使用insert()函数可以向集合中插入一个元素。如果元素已经存在(根据排序准则判断),则不会插入重复项。

    std::set<int> mySet;
    mySet.insert(42); // 尝试插入数字42
    
  2. 批量插入:可以通过迭代器范围或初始化列表一次性插入多个元素。重复元素会被自动忽略。

    mySet.insert({1, 2, 3, 4}); // 使用初始化列表批量插入
    std::vector<int> vec = {5, 6, 7};
    mySet.insert(vec.begin(), vec.end()); // 使用迭代器范围插入
    
2.删除元素
  1. 删除指定值:使用erase()函数并提供待删除元素的值。如果该值在集合中存在,则会删除所有匹配的元素。

    mySet.erase(42); // 删除值为42的所有元素(如果有)
    
  2. 通过迭代器删除:可以删除特定迭代器指向的元素。

    auto it = mySet.find(42); // 查找值为42的元素
    if (it != mySet.end()) {
        mySet.erase(it); // 删除找到的元素
    }
    
  3. 清空集合:使用clear()函数可以删除集合中的所有元素。

    mySet.clear(); // 清空整个集合
    
3.示例

下面是一个综合示例,展示了如何在std::set中插入和删除元素:

// 包含标准输入输出库和集合库
#include <iostream>
#include <set>
using namespace std;

/**
 * 打印集合中的元素
 * @param S 集合,其元素将被打印
 */
void printSet(const set<int>& S){
    // 遍历集合并打印每个元素
    for(auto &it : S){
        cout << it << " ";
    }
    // 换行以分隔不同集合的打印输出
    cout << endl;
}

int main(){
    // 初始化一个整数集合S,包含一组预定义的元素
    set<int>S = {1,8,9,6,3,4};
    // 打印集合S的初始状态
    printSet(S);
    // 向集合S中插入新元素11
    S.insert(11);
    // 打印插入11后的集合S
    printSet(S);
    // 从集合S中删除元素11
    S.erase(11);
    // 打印删除11后的集合S
    printSet(S);
    // 从集合S中删除第一个元素(即1)
    S.erase(S.begin());
    // 打印删除第一个元素后的集合S
    printSet(S);
    // 从集合S中删除第一个元素到第二个元素之间的所有元素(即删除1和3)
    S.erase(S.begin(),++S.begin());
    // 打印删除部分元素后的集合S
    printSet(S);
    // 清空集合S的所有元素
    S.clear();
    // 打印清空后的集合S
    printSet(S);
    return 0;
}

这段代码演示了如何插入单个和多个元素、尝试插入已存在的元素、删除特定值以及清空整个集合。

6.set容器的查找和统计

在C++的std::set容器中,查找和统计元素是通过几个核心成员函数完成的,这些操作利用了std::set的有序特性,提供了高效的实现。

1.查找元素
  • find(): 使用此函数可以查找集合中是否存在某个特定值的元素。如果找到,它会返回一个指向该元素的迭代器;如果没有找到,则返回end()迭代器。

    std::set<int>::iterator it = mySet.find(30);
    if (it != mySet.end()) {
        std::cout << "Found element: " << *it << std::endl;
    } else {
        std::cout << "Element not found." << std::endl;
    }
    
2.统计元素个数
  • count(): 对于std::set容器,由于它不存储重复元素,因此count()函数的结果只有两种可能:如果元素存在,返回1;如果不存在,返回0。这与std::multiset不同,后者可能返回大于1的计数。

    int numElements = mySet.count(30);
    std::cout << "Number of occurrences of 30: " << numElements << std::endl;
    
3.注意事项
  • 查找效率:由于std::set底层实现通常为红黑树,查找操作的平均时间复杂度为O(log n),其中n是容器中元素的数量,因此非常高效。
  • 统计意义:在std::set中,由于每个元素都是唯一的,count()函数主要用于逻辑上的确认某个值是否存在,而不用于计算重复次数,因为不会有重复。

结合查找和统计,可以有效地管理并检索std::set中的元素,进行条件检查、元素确认等操作。

// 包含输入输出流和集合的头文件
#include <iostream>
#include <set>
// 使用标准命名空间,简化代码中标准库函数的调用
using namespace std;

/**
 * 打印集合中的所有元素
 * @param S 一个整数集合,作为函数的输入
 */
void printSet(const set<int>& S){
    // 遍历集合中的每个元素,并打印它们
    for(auto &it : S){
        cout << it << " ";
    }
    // 换行,以便后续输出开始于新行
    cout << endl;
}

int main(){
    // 初始化一个整数集合S,包含一组有序的不重复整数
    set<int>S = {1,2,3,6,5,4,8,9};
    // 调用函数打印集合S的内容
    printSet(S);
    // 寻找集合中值为11的元素的位置
    auto pos = S.find(11);
    // 根据查找结果判断是否找到值为11的元素,并输出相应信息
    cout << (pos != S.end() ? "找到该数据" : "未找到") << endl;
    // 输出集合中值为1的元素的数量
    cout << S.count(1) << endl;
    // 程序正常结束
    return 0;
}
9.set和multiset的区别
// 包含标准输入输出库和集合库
#include <iostream>
#include <set>
using namespace std;

// 主函数,程序的入口点
int main(){
    // 创建一个集合对象S,集合内的元素保证唯一
    set<int>S;
    // 创建一个pair对象ret,用于存储插入操作的结果:迭代器和插入标志
    pair<set<int>::iterator ,bool>ret;

    // 尝试向集合S中插入元素10
    ret = S.insert(10);
    // 检查插入操作是否成功,如果成功则输出"success"
    if (ret.second){
        cout << "success" << endl;
    } else{
        cout << "fail" << endl;
    }

    // 再次尝试向集合S中插入元素10,由于集合内已存在,此次插入应失败
    ret = S.insert(10);
    // 检查插入操作是否成功,输出相应的信息
    if (ret.second){
        cout << "success" << endl;
    } else{
        cout << "fail" << endl;
    }

    // 创建一个多重集合对象MS,允许包含重复元素
    multiset<int>MS;
    // 向多重集合MS中插入元素100
    MS.insert(100);
    // 再次插入元素100,多重集合允许重复元素
    MS.insert(100);

    // 遍历多重集合MS,输出其中的所有元素
    for(auto &it : MS){
        cout << it << endl;
    }

    // 程序正常结束
    return 0;
}
9.pair对组的创建

在C++中,std::pair是一种方便的工具,用于将两个相关联的数据作为一个单元存储。这对处理映射关系、返回多值函数结果等场景非常有用。创建std::pair的方式有几种,以下是几种常见的方法:

1. 直接构造

可以直接通过构造函数创建std::pair对象,指定两个元素的类型和值。

std::pair<int, std::string> myPair(42, "Hello");
2. 使用make_pair函数

std::make_pair是一个辅助函数,可以根据提供的两个参数自动推导类型并创建std::pair对象。

auto anotherPair = std::make_pair(3.14, "Pi");
3. 初始化列表

C++11起,可以使用初始化列表语法创建std::pair,这在类型已知的情况下特别简洁。

std::pair<char, double> pairWithInitList{'A', 3.14159};
4. 结构化绑定(C++17起)

在C++17中引入了结构化绑定,可以直接解包std::pair(或tuple等)到单独的变量中,但这不是创建pair的方式,而是使用它的一种方式。

auto [key, value] = std::make_pair('Z', 26.0);
// key 现在是 'Z',value 是 26.0
5.示例

下面是一个综合示例,展示了不同方式创建std::pair并对它们进行操作:

// 包含标准输入输出库
#include <iostream>

// 使用标准命名空间,简化IO操作
using namespace std;

// 程序入口函数
int main(){
    // 创建一个pair对象,用于表示一个人的名字和年龄
    // string类型的first成员存储名字,int类型的second成员存储年龄
    pair<string,int>p("Jack",17);
    
    // 使用make_pair函数创建另一个pair对象,同样表示一个人的名字和年龄
    pair<string ,int>p1 = make_pair("Li",19);
    
    // 输出第一个pair对象的名字和年龄
    cout << p.first << " " << p.second << endl;
    
    // 输出第二个pair对象的名字和年龄
    cout << p1.first << " " << p1.second << endl;
    
    // 程序正常结束
    return 0;
}

这段代码演示了如何使用不同方法创建std::pair实例,并打印它们的值。注意,根据上下文和偏好,可以选择最适合的创建方式。

10.set内置数据类型排序
/**
 * @file main.cpp
 * @brief 此程序演示了如何使用自定义比较函数对象在set中存储整数并按降序遍历。
 *
 * Created by 86189 on 2024/7/2.
 */

#include <iostream>
#include <set>
using namespace std;

/**
 * @class Compare
 * @brief 自定义比较函数对象,用于比较两个整数,使得set按降序排列。
 */
class Compare {
public:
    /**
     * @brief 比较运算符重载,返回true当且仅当第一个整数大于第二个整数。
     *
     * @param a 第一个整数引用。
     * @param b 第二个整数引用。
     * @return 返回布尔值,表示a是否大于b。
     */
    bool operator()(const int &a, const int &b) const {
        return a > b;
    }
};

int main() {
    /**
     * @var S
     * @brief 使用自定义比较函数对象Compare的set容器,存储降序排列的整数。
     */
    set<int, Compare> S;

    // 向set中插入整数
    S.insert(10);
    S.insert(20);
    S.insert(15);

    /**
     * @brief 遍历set并打印其内容,展示降序排列的效果。
     */
    for (auto &it : S) {
        std::cout << it << std::endl;  // 输出降序排列的整数
    }

    return 0;  // 程序正常结束
}
11.set对自定义数据类型排序
// 包含必要的头文件
#include <iostream>
#include <set>
#include <utility>

// 使用标准命名空间,简化代码中标准库的调用
using namespace std;

/**
 * @brief 学生类定义
 * 
 * 该类用于表示学生的信息,包括姓名、性别和年龄。
 */
class Student{
public:
    // 使用移动语义优化构造函数参数传递,提高效率
    string name;
    string sex;
    int age{};
    /**
     * @brief 构造函数
     * 
     * @param name 学生的姓名
     * @param sex 学生的性别
     * @param age 学生的年龄
     */
    Student(string name,string sex,int age): name(std::move(name)),sex(std::move(sex)),age(age){

    }
};

/**
 * @brief 自定义比较函数类
 * 
 * 该类用于定义对学生对象的比较方式,这里比较的是学生的年龄。
 */
class Compare{
public:
    /**
     * @brief 比较两个学生对象的年龄
     * 
     * @param s1 第一个学生对象
     * @param s2 第二个学生对象
     * @return bool 如果s1的年龄大于s2的年龄返回true,否则返回false
     */
    bool operator()(const Student& s1,const Student& s2) const{
        return s1.age > s2.age;
    }
};

int main(){
    // 使用自定义比较函数类实例化set容器,用于存储学生对象
    set<Student,Compare>S;
    // 创建并插入学生对象到set中
    Student stu1("Jack","男",16);
    S.insert(stu1);
    Student stu2("Mala","男",18);
    S.insert(stu2);
    Student stu3("Joko","女",19);
    S.insert(stu3);
    Student stu4("Mali","男",17);
    S.insert(stu4);
    Student stu5("Doro","女",15);
    S.insert(stu5);
    // 遍历set容器,输出每个学生的信息
    for(auto &it : S){
        cout << it.name << " " << it.sex << " " << it.age << endl;
    }

    return 0;
}

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

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

相关文章

观成科技:某修改版哥斯拉Webshell流量分析

一、工具介绍 哥斯拉是一款webshell权限管理工具&#xff0c;由java语言开发。功能特点&#xff1a;全部类型的shell能绕过市面大部分的静态查杀、流量加密能绕过过市面绝大部分的流量Waf。哥斯拉Webshell还可以通过各种魔改&#xff0c;绕过流量检测设备&#xff0c;近期&…

【CSAPP】-attacklab实验

目录 实验目的与要求 实验原理与内容 实验设备与软件环境 实验过程与结果&#xff08;可贴图&#xff09; 实验总结 实验目的与要求 1. 强化机器级表示、汇编语言、调试器和逆向工程等方面基础知识&#xff0c;并结合栈帧工作原理实现简单的栈溢出攻击&#xff0c;掌握其基…

怎么快速给他人分享图片?扫描二维码看图的简单做法

现在通过二维码来查看图片是一种很常见的方法&#xff0c;通过二维码来查看图片不仅能够减少对手机存储空间的占用&#xff0c;而且获取图片变得更加方便快捷&#xff0c;只需要扫码就能够查看图片&#xff0c;有利于图片的展现。很多的场景中都有图片二维码的应用&#xff0c;…

注意!年龄越大,社交圈子越窄?其实这是老人的理性选择!数学家告诉你:何时该跳槽,何时该坚守!你必须知道的三个智慧:让你的人生更加精彩!

我们到底应该在什么情况下探索新事物&#xff0c;什么情况下专注于已有的东西呢&#xff1f;本质上来说&#xff0c;这个问题就是在询问&#xff0c;你究竟应该耗费精力去探索新的信息&#xff0c;还是专注从既有的信息中获取收获&#xff1f; 有人采访了临终的老人&#xff0c…

AI图生视频工具测试

环境&#xff1a; 即梦 pika LUMA 可灵 问题描述&#xff1a; AI图生视频工具测试下面是原图 解决方案&#xff1a; 1.即梦 效果 2.pika 生成效果 3.LUMA 生成效果还行 4.可灵 生成效果最好

Cookie的默认存储路径以及后端如何设置

问题场景 最近在写一个前后端分离的项目&#xff0c;需要跨域&#xff0c;前端开发同学遇到一个问题一直报错&#xff0c;本质上就是后端返回的cookie中的sessionID在前端发送http请求时无法被请求自动携带&#xff0c;每次htttpRequest都被后端识别为一个新的session&#xf…

Python 文件夹同步工具(sync_folders)

分享一个自己写的文件夹同步工具&#xff0c;可以实现文件夹备份/同步。 下载地址&#xff1a; https://download.csdn.net/download/frostlulu/89506856?spm1001.2014.3001.5501 使用方法&#xff1a; 下载后解压&#xff0c;会得到下面3个文件&#xff1a;sync_folders.…

Zabbix 配置钉钉告警

Zabbix 配置钉钉告警 随着企业IT运维需求的不断增加&#xff0c;及时、准确地获取系统告警信息显得尤为重要。在众多告警工具中&#xff0c;Zabbix 因其强大的监控功能和灵活的告警机制&#xff0c;成为了很多企业的首选。同时&#xff0c;随着企业内部沟通工具的多样化&#…

windows远程连接无法复制文件

windows远程桌面无法复制文件 解决方案 打开任务管理器管理器,在详细信息界面,找到rdpclip.exe进程&#xff0c;选中并点击结束任务&#xff0c;杀死该进程。 快捷键 win r 打开运行界面&#xff0c;输入 rdpclip.exe &#xff0c;点击确定运行。即可解决无法复制文件问题。…

ELK日志实时监控

目录 一、ELK/EFK简介 1.1 什么是ELK/EFK? 1.2 常见架构 1、Elasticsearch Logstash Kibana 2、Elasticsearch Logstash Filebeat Kibana 3、Elasticsearch Logstash Filebeat Kibana Redis 4、Elasticsearch Fluentd Filebeat Kibana 1.3 基本流程 二、…

Python层次密度聚类算法库之HDBSCAN使用详解

概要 HDBSCAN 是一种层次密度聚类算法,它通过密度连接性来构建聚类层次结构。与传统的 K-Means 算法相比,HDBSCAN 具有以下几个显著特点: 自动确定聚类数量:HDBSCAN 能够根据数据自动确定聚类数量,不需要预先指定。 适应噪声和异常点:HDBSCAN 在聚类过程中能够很好地处理…

2024年创业新商机组合拳“消费增值+二二复制”引流拓客新思路

文丨微三云胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 引言&#xff1a;2024年各行各业面临企业经营瓶颈难的一年&#xff0c;国家也陆续推出了《关于打造消费新场景培育消费新增长点的措施》都是为了培育和壮大消费新增长点&#xff…

大公司图纸管理的未来趋势

随着科技的不断发展&#xff0c;大公司图纸管理正朝着更加智能化、自动化和协同化的方向发展。以下是大公司图纸管理的未来趋势预测。 1. 智能化管理 利用人工智能和机器学习技术&#xff0c;实现图纸的自动分类、标注和检索。通过智能分析算法&#xff0c;预测图纸的使用趋势…

[方法] 为Cinemachine添加碰撞器

选中场景中的Cinemachine物体&#xff0c;在 Inspector 面板的最下方单击 Add Extension 下拉框&#xff0c;选择 CinemachineCollider。 之后在添加的碰撞器组件中选择要与之碰撞的层&#xff08;Collide Against&#xff09;和忽略的层&#xff08;Transparent Layers&#x…

V Rising夜族崛起的管理员指令大全

使用方法&#xff1a; 如果没有启用控制台需要先启用控制台 打开游戏点击选项&#xff08;如果在游戏内点击ESC即可&#xff09;&#xff0c;在通用页面找到启用控制台&#xff0c;勾选右边的方框启用 在游戏内点击键盘ESC下方的波浪键&#xff08;~&#xff09;使用控制台 指…

5.Android逆向协议-初识HTTP和HTTPS协议

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;微尘网校 上一个内容&#xff1a;4.Android逆向协议-详解二次打包失败解决方案 从现在开始正式进入协议分析了。 首先客户端与服务端之…

Sui Bridge激励计划更新,一周后结束

Sui Bridge的激励测试网阶段将于7月8日结束&#xff0c;这是最后一周参与的机会。在这一关键阶段&#xff0c;社区反馈和全面测试对于确保Sui Bridge在主网上线时的顺利运行至关重要。 为了确保你的操作符合奖励条件&#xff0c;请确保遵守以下要求&#xff1a; 完成完整的桥…

如何完成域名解析验证

一&#xff1a;什么是DNS解析&#xff1a; DNS解析是互联网上将人类可读的域名&#xff08;如www.example.com&#xff09;转换为计算机可识别的IP地址&#xff08;如192.0.2.1&#xff09;的过程&#xff0c;大致遵循以下步骤&#xff1a; 查询本地缓存&#xff1a;当用户尝…

[激光原理与应用-96]:激光器研发与生产所要的常见设备(大全)与仪器(图解)

目录 一、激光器制造设备 二、测试与校准设备 2.1 光功率计&#xff1a; 1、工作原理 2、主要功能 3、应用场景 4、测量方法 5、总结 2.2. 激光束质量分析仪&#xff1a; 1、概述 2、主要功能和特点 3、工作原理 4、常见品牌和型号 5、应用领域 6、总结 2.3 光…

【windows】亲测-win11系统跳过联网和微软账户登录,实现本地账户登录

问题原因&#xff1a;现在市面上销售的品牌笔记本和台式机基本上都预装了正版的Windows S11家族中文版操作系统&#xff0c;联网后系统会自动激活。在win11的版本中&#xff0c;隐藏了关闭跳过连接网络的按钮&#xff0c;默认强制需要注册微软账户登录才能正常使用。 一、跳过…