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

ranges::set_intersection set_union set_difference set_symmetric_difference

std::ranges::set_intersection:是 C++20 引入的一个算法,用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。

std::ranges::set_intersection 

用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。

注意事项

  1. 输入范围必须已排序
  2. 目标范围必须有足够空间存储交集结果
  3. 交集结果默认按升序排列。
  4. 若元素重复,交集次数取两范围中较小的重复次数(例如 a = [2, 2, 3]b = [2, 2, 2],则交集为 [2, 2])。

### 语法

Defined in header <algorithm>

Call signature

template< std::input_iterator I1, std::sentinel_for<I1> S1,

          std::input_iterator I2, std::sentinel_for<I2> S2,
          std::weakly_incrementable O, class Comp = ranges::less,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::mergeable<I1, I2, O, Comp, Proj1, Proj2>
constexpr set_intersection_result<I1, I2, O>
    set_intersection( I1 first1, S1 last1, I2 first2, S2 last2,
                      O result, Comp comp = {},

                      Proj1 proj1 = {}, Proj2 proj2 = {} );
(1)(since C++20)
template< ranges::input_range R1, ranges::input_range R2,

          std::weakly_incrementable O, class Comp = ranges::less,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::mergeable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                        O, Comp, Proj1, Proj2>
constexpr set_intersection_result<ranges::borrowed_iterator_t<R1>,
                                  ranges::borrowed_iterator_t<R2>, O>
    set_intersection( R1&& r1, R2&& r2, O result, Comp comp = {},

                      Proj1 proj1 = {}, Proj2 proj2 = {} );
(2)(since C++20)

Helper types

template< class I1, class I2, class O >
using set_intersection_result = ranges::in_in_out_result<I1, I2, O>;

(3)(since C++20)

### 参数
- `r1` 和 `r2`:输入范围,必须是已排序的。
- `result`:输出迭代器,指向存储交集元素的位置。
- `comp`:比较函数对象,用于比较元素。
- `proj1` 和 `proj2`:投影函数对象,用于投影元素。

### 返回值
返回一个 `ranges::set_intersection_result` 结构,包含两个输入范围的结束迭代器和输出范围的结束迭代器。

### 示例
以下是一个使用 `std::ranges::set_intersection` 的示例:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>void print(const auto& v, const auto& rem)
{std::cout << "{ ";for (const auto& e : v)std::cout << e << ' ';std::cout << '}' << rem;
}int main()
{const auto in1 = {1, 2, 2, 3, 4, 5, 6};const auto in2 = {2, 2, 3, 3, 5, 7};std::vector<int> out {};std::ranges::set_intersection(in1, in2, std::back_inserter(out));print(in1, " ∩ "), print(in2, " = "), print(out, "\n");
}

Output:

{ 1 2 2 3 4 5 6 } ∩ { 2 2 3 3 5 7 } = { 2 2 3 5 }

在这个示例中,`in1` 和 `in2` 是两个已排序的整数向量。`std::ranges::set_intersection` 计算它们的交集,并将结果存储在 `out` 向量中。最后,程序输出交集元素。

示例 2:自定义比较和投影
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>struct Person {std::string name;int age;
};int main() {std::vector<Person> a = {{"Alice", 20}, {"Bob", 25}, {"Charlie", 30}};std::vector<Person> b = {{"Bob", 25}, {"David", 28}, {"Eve", 30}};std::vector<Person> out;// 按 age 字段比较,计算交集std::ranges::set_intersection(a, b,std::back_inserter(out),[](int age1, int age2) { return age1 < age2; }, // 比较函数&Person::age, // 对 a 的投影:提取 age&Person::age  // 对 b 的投影:提取 age);// 输出结果:Bob(25), Charlie(30)for (const auto& p : out) {std::cout << p.name << "(" << p.age << ") ";}
}

更多请了解:https://en.cppreference.com/w/cpp/algorithm/ranges/set_intersection

std::ranges::set_union

std::ranges::set_union 是 C++20 引入的算法,用于合并两个已排序范围的并集,并将结果写入目标范围。

Defined in header <algorithm>

Call signature

template< std::input_iterator I1, std::sentinel_for<I1> S1,

          std::input_iterator I2, std::sentinel_for<I2> S2,
          std::weakly_incrementable O, class Comp = ranges::less,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::mergeable<I1, I2, O, Comp, Proj1, Proj2>
constexpr set_union_result<I1, I2, O>
    set_union( I1 first1, S1 last1, I2 first2, S2 last2,
               O result, Comp comp = {},

               Proj1 proj1 = {}, Proj2 proj2 = {} );
(1)(since C++20)
template< ranges::input_range R1, ranges::input_range R2,

          std::weakly_incrementable O, class Comp = ranges::less,
          class Proj1 = std::identity, class Proj2 = std::identity >
requires std::mergeable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                        O, Comp, Proj1, Proj2>
constexpr set_union_result<ranges::borrowed_iterator_t<R1>,
                           ranges::borrowed_iterator_t<R2>, O>
    set_union( R1&& r1, R2&& r2, O result, Comp comp = {},

               Proj1 proj1 = {}, Proj2 proj2 = {} );

参数说明

  1. first1last1:第一个输入范围的起止迭代器。
  2. first2last2:第二个输入范围的起止迭代器。
  3. result:目标范围的起始迭代器。
  4. comp:比较函数(默认为 std::ranges::less)。
  5. proj1proj2:对输入元素的投影函数(默认为 std::identity)。

要求

  1. 输入范围必须按 comp 定义的顺序排序
  2. 目标范围必须有足够空间存储并集结果。
  3. 重复元素处理
    • 若元素在某个范围中重复出现,并集会保留所有重复项(但不会跨范围合并)。
    • 例如:a = [2, 2, 3]b = [2, 2, 2],并集为 [2, 2, 2, 3]
  4. 目标空间:需确保目标范围有足够空间,或使用 std::back_inserter 动态扩展。
  5. 性能:时间复杂度为线性(最多 2*(N1 + N2) - 1 次比较,其中 N1 和 N2 为输入范围长度)。

返回值

返回指向目标范围末尾的迭代器

示例

示例 1:基本用法

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>int main() {std::vector<int> a = {1, 2, 3, 4, 5};std::vector<int> b = {3, 4, 5, 6, 7};std::vector<int> out;// 计算并集std::ranges::set_union(a, b, std::back_inserter(out));// 输出结果:1 2 3 4 5 6 7for (int x : out) {std::cout << x << " ";}
}

输出结果:

1 2 3 4 5 6 7

示例 2:自定义比较和投影
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>struct Person {std::string name;int age;
};int main() {std::vector<Person> a = {{"Alice", 20}, {"Bob", 25}, {"Charlie", 30}};std::vector<Person> b = {{"Bob", 26}, {"David", 28}, {"Eve", 30}};std::vector<Person> out;// 按 age 字段比较,计算并集std::ranges::set_union(a, b,std::back_inserter(out),[](int age1, int age2) { return age1 < age2; }, // 比较函数&Person::age, // 对 a 的投影:提取 age&Person::age  // 对 b 的投影:提取 age);// 输出结果:Alice(20), Bob(25), Charlie(30), David(28), Eve(30)for (const auto& p : out) {std::cout << p.name << "(" << p.age << ") ";}
}

输出结果:

Alice(20) Bob(25) Bob(26) David(28) Charlie(30) 

与传统 std::set_union 的区别

  • 范围支持:直接接受范围参数(如 std::ranges::set_union(a, b, ...)),而非迭代器对。
  • 投影功能允许通过 proj1 和 proj2 对输入元素进行变换后再比较
  • 约束检查:通过 C++20 概念明确约束参数类型,增强类型安全。

更多信息:

https://en.cppreference.com/w/cpp/algorithm/ranges/set_union


    std::ranges::set_difference

    Defined in header <algorithm>

    Call signature

    template< std::input_iterator I1, std::sentinel_for<I1> S1,

              std::input_iterator I2, std::sentinel_for<I2> S2,
              std::weakly_incrementable O, class Comp = ranges::less,
              class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::mergeable<I1, I2, O, Comp, Proj1, Proj2>
    constexpr set_difference_result<I1, O>
        set_difference( I1 first1, S1 last1, I2 first2, S2 last2,
                        O result, Comp comp = {},

                        Proj1 proj1 = {}, Proj2 proj2 = {} );
    (1)(since C++20)
    template< ranges::input_range R1, ranges::input_range R2,

              std::weakly_incrementable O, class Comp = ranges::less,
              class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::mergeable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                            O, Comp, Proj1, Proj2>
    constexpr set_difference_result<ranges::borrowed_iterator_t<R1>, O>
        set_difference( R1&& r1, R2&& r2, O result, Comp comp = {},

                        Proj1 proj1 = {}, Proj2 proj2 = {} );

    std::ranges::set_difference 是 C++20 引入的算法,用于计算两个已排序范围的差集(即存在于第一个范围但不在第二个范围中的元素),并将结果写入目标范围。它是传统 std::set_difference 的范围适配版本,支持投影和直接使用范围参数。


    参数说明

    1. first1last1:第一个输入范围的起止迭代器(要计算差集的主范围)。
    2. first2last2:第二个输入范围的起止迭代器(被减的范围)。
    3. result:目标范围的起始迭代器。
    4. comp:比较函数(默认为 std::ranges::less)。
    5. proj1proj2:对输入元素的投影函数(默认为 std::identity)。

    要求

    1. 两个输入范围必须按 comp 定义的顺序排序
    2. 目标空间:需确保目标范围有足够空间,或使用 std::back_inserter 动态扩展。
    3. 重复元素处理
      • 若元素在第一个范围中出现 m 次,在第二个范围中出现 n 次,则差集中保留 max(m - n, 0) 次。
      • 例如:a = [2, 2, 3]b = [2],差集为 [2, 3]
    4. 性能:时间复杂度为线性(最多 2*(N1 + N2) - 1 次比较,其中 N1 和 N2 为输入范围长度)。

    示例

    示例 1:基本用法
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <iterator>int main() {std::vector<int> a = {1, 2, 3, 4, 5};std::vector<int> b = {3, 4, 5, 6, 7};std::vector<int> out;// 计算差集:a 中存在但 b 中不存在的元素std::ranges::set_difference(a, b, std::back_inserter(out));// 输出结果:1 2for (int x : out) {std::cout << x << " ";}
    }
    

    输出结果:

    1 2

    示例 2:自定义比较和投影
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <string>struct Person {std::string name;int age;
    };int main() {std::vector<Person> a = {{"Alice", 20}, {"Bob", 25}, {"Charlie", 30}};std::vector<Person> b = {{"Bob", 26}, {"David", 28}, {"Eve", 30}};std::vector<Person> out;// 按 age 字段比较,计算差集(a 中存在但 b 中不存在的元素)std::ranges::set_difference(a, b,std::back_inserter(out),[](int age1, int age2) { return age1 < age2; }, // 比较函数&Person::age, // 对 a 的投影:提取 age&Person::age  // 对 b 的投影:提取 age);// 输出结果:Alice(20) Bob(25) for (const auto& p : out) {std::cout << p.name << "(" << p.age << ") ";}
    }

    输出结果:

    Alice(20) Bob(25)

    与传统 std::set_difference 的区别

    • 范围支持:直接接受范围参数(如 std::ranges::set_difference(a, b, ...))。
    • 投影功能:允许通过 proj1 和 proj2 对输入元素进行变换后再比较。
    • 约束检查:通过 C++20 概念明确约束参数类型,增强类型安全。

    std::ranges::set_symmetric_difference

    std::ranges::set_symmetric_difference 是 C++20 中引入的算法,用于计算两个有序范围的对称差集,即存在于任一输入范围但不同时存在于两个范围中的元素。结果会写入输出范围,且保持有序。

    函数原型

    Defined in header <algorithm>

    Call signature

    template< std::input_iterator I1, std::sentinel_for<I1> S1,

              std::input_iterator I2, std::sentinel_for<I2> S2,
              std::weakly_incrementable O, class Comp = ranges::less,
              class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::mergeable<I1, I2, O, Comp, Proj1, Proj2>
    constexpr set_symmetric_difference_result<I1, I2, O>
        set_symmetric_difference( I1 first1, S1 last1, I2 first2, S2 last2,
                                  O result, Comp comp = {},

                                  Proj1 proj1 = {}, Proj2 proj2 = {} );
    (1)(since C++20)
    template< ranges::input_range R1, ranges::input_range R2,

              std::weakly_incrementable O, class Comp = ranges::less,
              class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::mergeable<ranges::iterator_t<R1>, ranges::iterator_t<R2>,
                            O, Comp, Proj1, Proj2>
    constexpr set_symmetric_difference_result<ranges::borrowed_iterator_t<R1>,
                                              ranges::borrowed_iterator_t<R2>, O>
        set_symmetric_difference( R1&& r1, R2&& r2, O result, Comp comp = {},

                                  Proj1 proj1 = {}, Proj2 proj2 = {} );

    参数说明

    • first1, last1: 第一个输入范围的迭代器对。
    • first2, last2: 第二个输入范围的迭代器对。
    • result: 输出范围的起始迭代器。
    • comp: 比较函数(默认为 std::ranges::less)。
    • proj1, proj2: 应用于输入元素的投影(默认为 std::identity)。

    使用条件

    1. 输入范围必须已按升序排列。
    2. 输出范围不能与输入范围重叠。

    示例

    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <iterator>int main() {std::vector<int> v1 = {1, 2, 4, 5, 6};std::vector<int> v2 = {2, 3, 5, 7};std::vector<int> out;std::ranges::set_symmetric_difference(v1, v2, std::back_inserter(out));// 输出结果for (int n : out) {std::cout << n << ' ';}
    }
    

    输出:

    1 3 4 6 7

    步骤解析

    1. 输入准备v1 和 v2 必须有序。
    2. 算法执行:
      • 比较 v1 和 v2 的当前元素。
      • 将较小元素写入 out,移动对应迭代器。
      • 若元素相等,则跳过,同时移动两个迭代器。
    3. 结果out 包含对称差集元素,保持有序。

    自定义比较和投影

    // 使用自定义比较函数(按降序)
    std::ranges::set_symmetric_difference(v1 | std::views::reverse,v2 | std::views::reverse,std::back_inserter(out),std::greater{}
    );// 使用投影(如比较字符串长度)
    std::vector<std::string> s1 = {"apple", "banana", "cherry"};
    std::vector<std::string> s2 = {"grape", "kiwi", "orange"};
    std::ranges::set_symmetric_difference(s1, s2, std::back_inserter(out_str),[](int a, int b) { return a < b; },[](const std::string& s) { return s.length(); },[](const std::string& s) { return s.length(); }
    );
    

     总结

    std::ranges::set_symmetric_difference 高效计算两个有序范围的对称差集,时间复杂度为 (O(N+M)),空间复杂度为 (O(1))(不计输出)。需确保输入有序且输出范围足够大。

        相关文章:

        ranges::set_intersection set_union set_difference set_symmetric_difference

        std::ranges::set_intersection&#xff1a;是 C20 引入的一个算法&#xff0c;用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。 std::ranges::set_intersection 用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。 注意事项…...

        在IDEA的Maven中(同步所有Maven项目)和(重新加载所有Maven项目)的区别

        特性同步所有 Maven 项目 (Sync All Maven Projects)重新加载所有 Maven 项目 (Reload All Maven Projects)主要作用使 IDEA 项目结构、依赖关系与 pom.xml 文件同步。强制重新读取所有 pom.xml 文件&#xff0c;并重建 IDEA 的 Maven 项目模型。缓存使用 IDEA 缓存的 Maven 项…...

        如何查询网站是否被百度蜘蛛收录?

        一、使用site命令查询 这是最直接的方法。在百度搜索框中输入“site:你的网站域名”&#xff0c;例如“site.com”&#xff08;请将“example.com”替换为你实际的网站域名&#xff09;。如果搜索结果显示了你的网站页面&#xff0c;并且显示了收录的页面数量&#xff08;如“…...

        el-table树状表格,默认展开第一个节点的每一层

        效果如图 <template><el-table:data"tableData"style"width: 100%":tree-props"{ children: children, hasChildren: hasChildren }":expand-row-keys"expandRowKeys"row-key"id"expand-change"handleExpan…...

        express-validator 数据校验详解

        express-validator 是一个用于在 Express 应用中进行数据验证和清理的中间件。 一、安装 # 使用 npm 安装npm install express-validator 二、基本使用 1. 引入和初始化 const express require("express");const { body, validationResult } require("ex…...

        使用VSCODE开发C语言程序

        使用vscode配置C语言开发环境 一、安装VSCODE 1、下载vscode ​ 从官方网站&#xff08;https://code.visualstudio.com/Download&#xff09;上&#xff0c;下载windows版本的vscode 2、安装vscode ​ 下载完毕后&#xff0c;按照提示进行安装即可&#xff08;尽可能不要安…...

        Python学习心得常用的内置函数

        常用的内置函数&#xff1a; 1.数据类型转换函数&#xff1a; 描述说明 描述说明 bool(obj) 获取指定对象 obj 的布尔值 str(obj) 将指定对象 obj 转成字符串类型 int(x) 将 x 转成 int 类型 float(x) 将 x 转成 float 类型 list(sequence) 将序列转成列表类型 tu…...

        【数据结构初阶第十二节】设计循环队列

        云边有个稻草人-CSDN博客 必须有为成功付出代价的决心&#xff0c;然后想办法付出这个代价。 还有最后一道关于队列的习题&#xff0c;这题有点难&#xff0c;准备好迎接挑战吧&#xff01; 目录 1.【题目】 2.实现循环队列推荐用数组&#xff0c;Why? 3.Q1&#xff1a;如…...

        【数据分享】1929-2024年全球站点的逐年降雪深度数据(Shp\Excel\免费获取)

        气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2024年全球气象站…...

        【强化学习的数学原理】第10课-Actor-Critic方法-笔记

        学习资料&#xff1a;bilibili 西湖大学赵世钰老师的【强化学习的数学原理】课程。链接&#xff1a;强化学习的数学原理 西湖大学 赵世钰 文章目录 一、最简单的Actor-Critic&#xff08;QAC&#xff09;二、Advantage Actor-Critic&#xff08;A2C&#xff09;三、重要性采样和…...

        scratch猜年龄互动小游戏 2024年12月scratch四级真题 中国电子学会 图形化编程 scratch四级真题和答案解析

        scratch猜年龄互动小游戏 2024年12月电子学会图形化编程Scratch等级考试四级真题 一、题目要求 老爷爷的年龄是1-100的随机数,老爷爷询问“请猜猜我的年龄是多少?”,输入年龄,老爷爷会回答"大了"或者"小了,直到最后成功猜出年龄。 1、准备工作 (1)删…...

        javaSE学习笔记23-线程(thread)-总结

        创建线程的三种方式 练习代码 package com.kuang.thread;import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask;//回顾总结线程的创建 public class ThreadNew {public static void main(String[…...

        Boringssl介绍

        BoringSSL 是 Google 从 OpenSSL 分支出来的一个开源 TLS/SSL 库&#xff0c;旨在为 Google 的产品和服务提供一个更加轻量、安全和现代化的加密库。它是 OpenSSL 的一个替代品&#xff0c;专注于简化代码、提高安全性和减少潜在的攻击面。 以下是对 BoringSSL 的详细介绍&…...

        java每日精进 2.13 MySql迁移人大金仓

        1.迁移数据库 1. 数据库创建语句 MySQL&#xff1a; CREATE DATABASE dbname; 人大金仓&#xff08;Kingbase&#xff09;&#xff1a; 在人大金仓中&#xff0c;CREATE DATABASE 的语法通常相同&#xff0c;但可能需要特别注意字符集的指定&#xff08;如果涉及到多语言支持…...

        2025最新智能优化算法:改进型雪雁算法(Improved Snow Geese Algorithm, ISGA)求解23个经典函数测试集,MATLAB

        一、改进型雪雁算法 雪雁算法&#xff08;Snow Geese Algorithm&#xff0c;SGA&#xff09;是2024年提出的一种新型元启发式算法&#xff0c;其灵感来源于雪雁的迁徙行为&#xff0c;特别是它们在迁徙过程中形成的独特“人字形”和“直线”飞行模式。该算法通过模拟雪雁的飞行…...

        C++中为什么有了tuple还需要pair?

        在C中&#xff0c;tuple和pair都是用于存储多个值的工具。tuple可以存储任意数量的元素&#xff0c;而pair只能存储两个元素。既然tuple的功能更强大&#xff0c;为什么C标准库仍然保留了pair呢&#xff1f;本文将从多个角度探讨这个问题。 1. 历史兼容性 pair在C标准库中比tu…...

        Open WebUI项目源码学习记录(从0开始基于纯CPU环境部署一个网页Chat服务)

        感谢您点开这篇文章:D&#xff0c;鼠鼠我是一个代码小白&#xff0c;下文是学习开源项目Open WebUI过程中的一点笔记记录&#xff0c;希望能帮助到你&#xff5e; 本人菜鸟&#xff0c;持续成长&#xff0c;能力不足有疏漏的地方欢迎一起探讨指正&#xff0c;比心心&#xff5e…...

        什么是Grok-3?技术特点,场景,潜在问题与挑战

        Grok-3 的技术特点与优势 1. 超大算力与训练规模 算力投入:Grok-3 使用了 20 万块英伟达 H100 GPU,分两个阶段训练(第一阶段 10 万 GPU 训练 144 天,第二阶段 20 万 GPU 训练 92 天),总计算量是前代 Grok-2 的 10 倍。这种规模远超同期其他项目(如印度的 1.8 万 GPU 公…...

        容器docker k8s相关的问题汇总及排错

        1.明确问题 2.排查方向 2.1、 docker方面 docker logs -f 容器ID docker的网络配置问题。 2.2、 k8s方面 node组件问题 pod的问题&#xff08;方式kubectl describe po pod的名称 -n 命名空间 && kubectl logs -f pod的名称 -n 命名空间&#xff09; 调度的问题&#x…...

        【Docker】百度网盘:基于VNC的Web访问及后台下载

        本教程通过 Docker Compose 部署百度网盘的 VNC 版本&#xff0c;实现24小时不间断下载、双模式访问、数据持久化、自动重启和安全加密控制等核心功能。 目录结构规划 建议使用以下目录结构&#xff08;可根据实际情况调整&#xff09;&#xff1a; ~/baidunetdisk/├── d…...

        JWT 令牌

        目录 一、JWT 1、什么是JWT 2、JWT的组成 3、JJWT签发与验证token 1、创建token 2、解析token 3、设置过期时间 4、自定义claims 前言&#xff1a; 在现代Web应用和微服务架构中&#xff0c;用户身份验证和信息安全传输是核心问题。JSON Web Token&#xff08;J…...

        鼎捷PLM深度集成DeepSeek,领跑智能研发新赛道

        新年伊始&#xff0c;DeepSeek以其卓越的性能、高性价比和开源优势&#xff0c;掀起一股AI技术应用热潮&#xff0c;重塑各行各业的知识管理、知识应用模式。对制造业来说&#xff0c;首当其冲的就是研发管理变革&#xff0c;这也引发了企业的深度思考&#xff1a;在工业领域的…...

        设计模式之适配模式是什么?以及在Spring AOP中的拦截器链的使用源码解析。

        前言 本文涉及到适配模式的基本用法&#xff0c;以及在Spring AOP中如何使用&#xff0c;首先需要了解适配模式的工作原理&#xff0c;然后结合Spring AOP的具体实现来详细详细解析源码。 首先&#xff0c;适配模式&#xff0c;也就是Adapter Pattern&#xff0c;属于结构型设计…...

        挖掘图片的秘密:如何用piexif提取和修改Exif数据

        Exif&#xff08;Exchangeable Image File Format&#xff09;数据是一个广泛用于数字图像&#xff08;尤其是JPEG和TIFF格式&#xff09;中的元数据格式。它包含了关于图像的各种信息&#xff0c;包括拍摄设备的类型、拍摄时间、光圈、曝光时间、GPS定位信息等。Exif数据使得用…...

        javaSE学习笔记22-线程(thread)-线程通信、线程池

        线程通信 应用场景&#xff1a;生产者和消费者问题 假设仓库中只能存放一件产品&#xff0c;生产者将生产出来的产品放入仓库&#xff0c;消费者将仓库中产品取走消费 如果仓库中没有产品&#xff0c;则生产者将产品放入仓库&#xff0c;否则停止生产并等待&#xff0c…...

        VMware新建虚拟机

        看看自己的电脑是什么内核&#xff0c;有几个处理器 再分配给虚拟机 镜像文件需要自己安装下载地方https://mirrors.aliyun.com/centos/?spma2c6h.13651104.d-2001.8.3fb1320cuI1jeS 然后就出现了 然后开启虚拟机&#xff0c;等待 等待之后如下&#xff0c;选择语言 等待一段时…...

        Windows 11运行《拳皇98UM》等老游戏闪退解决方案

        问题&#xff1a;游戏可以进入选项菜单&#xff0c;但只要进行键盘操作就会卡死并闪退。 问题分析&#xff1a;该游戏兼容DirectX 9&#xff0c;但可能不向上兼容。而Windows 11默认安装的是DirectX 12&#xff0c;并不兼容低版本的DirectX&#xff0c;这可能导致该游戏或其他…...

        使用iOS个人声音与SoVITS训练个人AI语音(10分钟快速上手)

        使用iOS个人声音与SoVITS训练个人AI语音&#xff08;10分钟快速上手&#xff09; 序言&#xff1a;最近在抖音上频繁看到曼波唱歌的视频和各种AI语音的搞笑短片&#xff0c;加上年后新购置的M2硬盘终于提供了足够的存储空间&#xff0c;让我有机会深入研究AI语音训练。24年年初…...

        【JavaEE进阶】Spring MVC(3)

        欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ 返回响应 返回静态页面 //RestController Controller RequestMapping("/response") public class ResponseController {RequestMapping("/returnHtmlPage&…...

        火语言RPA--Excel读取内容

        【组件功能】&#xff1a;读取Excel内指定位置的内容或读取整篇Sheet页内容 配置预览 配置说明 读取位置 单元格&#xff1a;读取指定单元格中的内容。 行&#xff1a;读取指定行内容。 列&#xff1a;读取指定列内容。 区域&#xff1a;读取指定区域内容。 整篇sheet页&…...