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

C++11标准模板(STL)- 算法库 - 类似 std::accumulate,但不依序执行 -(std::reduce)

算法库

算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first, last) ,其中 last 指代要查询或修改的最后元素的后一个元素。

类似 std::accumulate,但不依序执行

std::reduce
template<class InputIt>

typename std::iterator_traits<InputIt>::value_type reduce(

    InputIt first, InputIt last);
(1)(C++17 起)
template<class ExecutionPolicy, class ForwardIt>

typename std::iterator_traits<ForwardIt>::value_type reduce(
    ExecutionPolicy&& policy,

    ForwardIt first, ForwardIt last);
(2)(C++17 起)

template<class InputIt, class T>
T reduce(InputIt first, InputIt last, T init);

(3)(C++17 起)
template<class ExecutionPolicy, class ForwardIt, class T>

T reduce(ExecutionPolicy&& policy,

         ForwardIt first, ForwardIt last, T init);
(4)(C++17 起)

template<class InputIt, class T, class BinaryOp>
T reduce(InputIt first, InputIt last, T init, BinaryOp binary_op);

(5)(C++17 起)
template<class ExecutionPolicy, class ForwardIt, class T, class BinaryOp>

T reduce(ExecutionPolicy&& policy,

         ForwardIt first, ForwardIt last, T init, BinaryOp binary_op);
(6)(C++17 起)

1) 同 reduce(first, last, typename std::iterator_traits<InputIt>::value_type{})

3) 同 reduce(first, last, init, std::plus<>())

5) 在 binary_op 上以初值 init 规约范围 [first; last) ,可能以未指定方式排序聚合。

2,4,6) 同 (1,3,5) ,但按照 policy 执行。此重载仅若std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 为 true才参与重载决议

binary_op 非结合或非交换,则行为非确定。

binary_op 修改 [first; last] 中任何元素或非法化范围中任何迭代器,含尾迭代器,则行为未定义。

参数

first, last-要应用算法的元素范围
init-广义和的初值
policy-使用的执行策略。细节见执行策略。
binary_op-将以未指定顺序应用于解引用输入迭代器结果、其他 binary_op 结果及 init 上的二元函数对象 (FunctionObject) 。
类型要求
- InputIt 必须满足遗留输入迭代器 (LegacyInputIterator) 的要求。
- ForwardIt 必须满足遗留向前迭代器 (LegacyForwardIterator) 的要求。
- T 必须满足可移动构造 (MoveConstructible) 的要求。而且 binary_op(init, *first)binary_op(*first, init)binary_op(init, init)binary_op(*first, *first) 必须可转换到 T

返回值

init*first*(first+1) 、…… *(last-1)binary_op 上的广义和,

其中广义和 GSUM(op, a
1, ..., a
N) 定义如下:

  • 若 N=1 ,则为 a
    1
  • 若 N > 1 ,则为 op(GSUM(op, b
    1, ..., b
    K), GSUM(op, b
    M, ..., b
    N)) ,其中
  • b
    1, ..., b
    N 可以是任何 a1, ..., aN 的排列,且
  • 1 < K+1 = M ≤ N

换言之, reduce 表现类似 std::accumulate ,除了范围中的元素可能以任意顺序分组并重排。

复杂度

O(last - first) 次应用 binary_op.

异常

拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

  • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
  • 若算法无法分配内存,则抛出 std::bad_alloc 。

注意

若为空,则返回不修改的 init

调用示例

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <random>
#include <vector>
#include <cassert>struct Cell
{int x;int y;Cell() = default;Cell(int a, int b): x(a), y(b) {}Cell &operator +=(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator +(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator *(const Cell &cell){x *= cell.x;y *= cell.y;return *this;}Cell &operator ++(){x += 1;y += 1;return *this;}bool operator <(const Cell &cell) const{if (x == cell.x){return y < cell.y;}else{return x < cell.x;}}bool operator >(const Cell &cell) const{if (x == cell.x){return y > cell.y;}else{return x > cell.x;}}bool operator ==(const Cell &cell) const{return x == cell.x && y == cell.y;}friend Cell operator+(const Cell &lcell, const Cell &rcell){Cell cell = lcell;cell.x += rcell.x;cell.y += rcell.y;return cell;}friend Cell operator-(const Cell &lcell, const Cell &rcell){Cell cell = lcell;cell.x -= rcell.x;cell.y -= rcell.y;return cell;}friend Cell operator*(const Cell &lcell, const Cell &rcell){Cell cell = lcell;cell.x *= rcell.x;cell.y *= rcell.y;return cell;}friend Cell operator/(const Cell &lcell, const Cell &rcell){Cell cell = lcell;cell.x /= rcell.x;cell.y /= rcell.y;return cell;}friend Cell operator%(const Cell &lcell, const Cell &rcell){Cell cell = lcell;cell.x %= rcell.x;cell.y %= rcell.y;return cell;}
};std::ostream &operator<<(std::ostream &os, const Cell &cell)
{os << "{" << cell.x << "," << cell.y << "}";return os;
}namespace std
{
template <typename InputIt, typename T, typename BinaryOperation>
T reduce(InputIt first, InputIt last, T init, BinaryOperation op)
{for (; first != last; ++first){init = op(std::move(init), *first);}return init;
}
}int main()
{std::cout << std::boolalpha;std::mt19937 g{std::random_device{}()};srand((unsigned)time(NULL));auto generate = [](){int n = std::rand() % 10 + 110;Cell cell{n, n};return cell;};//3) 构造拥有 count 个有值 value 的元素的容器。std::vector<Cell> vector1(8, generate());std::generate(vector1.begin(), vector1.end(), generate);std::sort(vector1.begin(), vector1.end());std::cout << "vector1:  ";std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;std::vector<Cell> vector2(vector1.size(), generate());std::generate(vector2.begin(), vector2.end(), generate);std::sort(vector2.begin(), vector2.end());std::cout << "vector2:  ";std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;for (size_t index = 0; index < vector1.size(); ++index){std::cout << "std::reduce(vector1.begin(), " << index << ", Cell{0, 0} std::plus<Cell>() ):    ";std::cout << std::reduce(vector1.begin(), vector1.begin() + index, Cell{0, 0}, std::plus<Cell>());std::cout << std::endl;}std::cout << std::endl;for (size_t index = 0; index < vector1.size(); ++index){std::cout << "std::reduce(vector1.begin(), " << index << ", Cell{0, 0} std::minus<Cell>() ):    ";std::cout << std::reduce(vector1.begin(), vector1.begin() + index, Cell{0, 0}, std::minus<Cell>());std::cout << std::endl;}std::cout << std::endl;for (size_t index = 0; index < vector2.size(); ++index){std::cout << "std::reduce(vector2.begin(), " << index << ", Cell{1, 1} std::multiplies<Cell>() ):    ";std::cout << std::reduce(vector2.begin(), vector2.begin() + index, Cell{1, 1}, std::multiplies<Cell>());std::cout << std::endl;}std::cout << std::endl;for (size_t index = 0; index < vector2.size(); ++index){std::cout << "std::reduce(vector2.begin(), " << index << ", Cell{1024, 1024} std::divides<Cell>() ):    ";std::cout << std::reduce(vector2.begin(), vector2.begin() + index, Cell{1024, 1024}, std::divides<Cell>());std::cout << std::endl;}std::cout << std::endl;for (size_t index = 0; index < vector2.size(); ++index){std::cout << "std::reduce(vector2.begin(), " << index << ", Cell{1024, 1024} std::modulus<Cell>() ):    ";std::cout << std::reduce(vector2.begin(), vector2.begin() + index, Cell{1024, 1024}, std::modulus<Cell>());std::cout << std::endl;}std::cout << std::endl;return 0;
}

输出

vector1:  {111,111} {112,112} {113,113} {115,115} {116,116} {116,116} {117,117} {119,119}
vector2:  {110,110} {112,112} {112,112} {114,114} {117,117} {117,117} {119,119} {119,119}
std::reduce(vector1.begin(), 0, Cell{0, 0} std::plus<Cell>() ):    {0,0}
std::reduce(vector1.begin(), 1, Cell{0, 0} std::plus<Cell>() ):    {111,111}
std::reduce(vector1.begin(), 2, Cell{0, 0} std::plus<Cell>() ):    {223,223}
std::reduce(vector1.begin(), 3, Cell{0, 0} std::plus<Cell>() ):    {336,336}
std::reduce(vector1.begin(), 4, Cell{0, 0} std::plus<Cell>() ):    {451,451}
std::reduce(vector1.begin(), 5, Cell{0, 0} std::plus<Cell>() ):    {567,567}
std::reduce(vector1.begin(), 6, Cell{0, 0} std::plus<Cell>() ):    {683,683}
std::reduce(vector1.begin(), 7, Cell{0, 0} std::plus<Cell>() ):    {800,800}std::reduce(vector1.begin(), 0, Cell{0, 0} std::minus<Cell>() ):    {0,0}
std::reduce(vector1.begin(), 1, Cell{0, 0} std::minus<Cell>() ):    {-111,-111}
std::reduce(vector1.begin(), 2, Cell{0, 0} std::minus<Cell>() ):    {-223,-223}
std::reduce(vector1.begin(), 3, Cell{0, 0} std::minus<Cell>() ):    {-336,-336}
std::reduce(vector1.begin(), 4, Cell{0, 0} std::minus<Cell>() ):    {-451,-451}
std::reduce(vector1.begin(), 5, Cell{0, 0} std::minus<Cell>() ):    {-567,-567}
std::reduce(vector1.begin(), 6, Cell{0, 0} std::minus<Cell>() ):    {-683,-683}
std::reduce(vector1.begin(), 7, Cell{0, 0} std::minus<Cell>() ):    {-800,-800}std::reduce(vector2.begin(), 0, Cell{1, 1} std::multiplies<Cell>() ):    {1,1}
std::reduce(vector2.begin(), 1, Cell{1, 1} std::multiplies<Cell>() ):    {110,110}
std::reduce(vector2.begin(), 2, Cell{1, 1} std::multiplies<Cell>() ):    {12320,12320}
std::reduce(vector2.begin(), 3, Cell{1, 1} std::multiplies<Cell>() ):    {1379840,1379840}
std::reduce(vector2.begin(), 4, Cell{1, 1} std::multiplies<Cell>() ):    {157301760,157301760}
std::reduce(vector2.begin(), 5, Cell{1, 1} std::multiplies<Cell>() ):    {1224436736,1224436736}
std::reduce(vector2.begin(), 6, Cell{1, 1} std::multiplies<Cell>() ):    {1525177344,1525177344}
std::reduce(vector2.begin(), 7, Cell{1, 1} std::multiplies<Cell>() ):    {1107477504,1107477504}std::reduce(vector2.begin(), 0, Cell{1024, 1024} std::divides<Cell>() ):    {1024,1024}
std::reduce(vector2.begin(), 1, Cell{1024, 1024} std::divides<Cell>() ):    {9,9}
std::reduce(vector2.begin(), 2, Cell{1024, 1024} std::divides<Cell>() ):    {0,0}
std::reduce(vector2.begin(), 3, Cell{1024, 1024} std::divides<Cell>() ):    {0,0}
std::reduce(vector2.begin(), 4, Cell{1024, 1024} std::divides<Cell>() ):    {0,0}
std::reduce(vector2.begin(), 5, Cell{1024, 1024} std::divides<Cell>() ):    {0,0}
std::reduce(vector2.begin(), 6, Cell{1024, 1024} std::divides<Cell>() ):    {0,0}
std::reduce(vector2.begin(), 7, Cell{1024, 1024} std::divides<Cell>() ):    {0,0}std::reduce(vector2.begin(), 0, Cell{1024, 1024} std::modulus<Cell>() ):    {1024,1024}
std::reduce(vector2.begin(), 1, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}
std::reduce(vector2.begin(), 2, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}
std::reduce(vector2.begin(), 3, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}
std::reduce(vector2.begin(), 4, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}
std::reduce(vector2.begin(), 5, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}
std::reduce(vector2.begin(), 6, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}
std::reduce(vector2.begin(), 7, Cell{1024, 1024} std::modulus<Cell>() ):    {34,34}

相关文章:

C++11标准模板(STL)- 算法库 - 类似 std::accumulate,但不依序执行 -(std::reduce)

算法库 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 类似 std::accumulate&#xff0c;但不依序执行 std…...

反射机制的介绍

什么是反射 Java反射机制是Java语言一个很重要的特性&#xff0c;它使得Java具有了“动态性”。在Java程序运行时&#xff0c;对于任意的一个类&#xff0c;我们能不能知道这个类有哪些属性和方法呢&#xff1f;对于任意的一个对象&#xff0c;我们又能不能调用它任意的方法&a…...

AI图文带货,手把手教学,傻瓜操作,轻松日入500+,小白教程

通过自媒体的力量&#xff0c;帮助普通人成为企业家。 建立自己的财富事业&#xff0c;用你的影响力帮助更多的人。 从而实现你更加自由的生活方式。 记住关注我&#xff0c;不要错过每一次分享。 对标账号 作为公司的一个项目实际拆解者&#xff0c;最热门的项目怎么能不拆…...

java:实现简单的验证码功能

效果 实现思路 验证码图片的url由后端的一个Controller生成&#xff0c;前端请求这个Controller接口的时候根据当前时间生成一个uuid&#xff0c;并把这个uuid在前端使用localStorage缓存起来&#xff0c;下一次还是从缓存中获取。 Controller生成验证码之后&#xff0c;把前…...

MybatisPlus使用指南

MybatisPlus 1. 快速入门1.1 入门案例1.2 常见注解1.3 常见配置 2. 核心功能2.1 条件构造器2.2 自定义SQL2.3 Service接口 3. 扩展功能3.1 代码生成3.2 静态工具3.3 逻辑删除 4. 插件功能4.1 分页插件4.2 通用分页实体 1. 快速入门 1.1 入门案例 步骤一&#xff1a;引入Mybat…...

5. MongoDB 集合创建、更新、删除

1. 创建集合 1.1 语法 db.createCollection(name, options) 参数说明&#xff1a; name: 要创建的集合名称。options: 可选参数, 指定有关内存大小及索引的选项。 options 可以是如下参数&#xff1a; 参数名类型描述示例值capped布尔值是否创建一个固定大小的集合。truesize…...

PHP中如何将变量从函数传递给acf_add_filter

在PHP开发中&#xff0c;我们有时需要将变量从函数传递给acf的add_filter钩子。这样做可以让我们在acf字段加载时&#xff0c;对字段值进行动态修改。下面&#xff0c;我将详细介绍如何实现这一功能。 在acf中&#xff0c;我们使用add_filter来添加钩子&#xff0c;对字段的加…...

KNN算法的使用

目录 一、KNN 算法简介 二、KNN算法的使用 1.读取数据 2.处理数据 三、训练模型 1.导入KNN模块 2.训练模型 3.出厂前测试 四、进行测试 1.处理数据 2.进行测试 总结 一、KNN 算法简介 KNN 是一种基于实例的学习算法。它通过比较样本之间的距离来进行预测。算法的核心…...

java文件上传

导入jar包&#xff0c;或者maven <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>…...

MySQL 数据库经验总结

一、数据库操作 1. 创建数据库 CREATE DATABASE database_name;例如&#xff0c;创建一个名为 my_database 的数据库&#xff1a; CREATE DATABASE my_database;2. 选择数据库 USE database_name;要使用刚才创建的 my_database 数据库&#xff1a; USE my_database;3. 删除…...

Python环境安装及PIP安装(Mac OS版)

官网 https://www.python.org/downloads/ 安装python python-3.12.1-macos11.pkg下载后&#xff0c;安装一直下一步即可 验证是否安装成功&#xff0c;执行python3命令和pip3命令 配置环境变量 获取python3安装位置并配置在.bash_profile #查看python路径 which python3#…...

2024自动驾驶(多模态)大模型综述:从DriveGPT4、DriveMLM到DriveLM、DriveVLM

前言 由于今年以来&#xff0c;一直在不断深挖具身智能机器人相关&#xff0c;而自动驾驶其实和机器人有着无比密切的联系&#xff0c;甚至可以认为&#xff0c;汽车就是一个带着4个轮子的机器人 加之个人认为&#xff0c;目前大模型落地潜力最大的两个方向&#xff0c;一个是…...

晨控CK-GW08-EC与汇川AC801系列PLC的EtherCAT通讯连接说明手册

晨控CK-GW08-EC与汇川AC801系列PLC的EtherCAT通讯连接说明手册 晨控CK-GW08-EC是一款支持标准工业通讯协议EtherCAT的网关控制器,方便用户集成到PLC等控制系统中。系统还集成了8路读写接口&#xff0c;用户可通过通信接口使用EtherCAT协议对8路读写接口所连接的读卡器进行相对…...

向上or向下调整建堆 的时间复杂度的本质区别的讲解

知识点&#xff1a;&#xff08;N代表节点数&#xff0c;h代表高度&#xff09; 1&#xff1a;高度为h的满二叉树节点个数N为 2^&#xff08;h&#xff09;-1 即N 2^&#xff08;h&#xff09;-1 2&#xff1a;所以h log&#xff08;N1&#xff09; 一&#xff1a;向上…...

阿一网络安全实战演练之利用 REST URL 中的服务器端参数污染

所需知识 要解决这个实验室问题&#xff0c;您需要了解以下内容&#xff1a; 如何确定用户输入是否包含在服务器端的 URL 路径或查询字符串中。如何使用路径遍历序列尝试更改服务器端请求。如何查找 API 文档。 这些内容在我们的 API 测试学院主题中有涵盖。 进入实验室 研…...

[游戏开发] LuaTable转string存读二进制文件

UE5和Unity通用此方案&#xff0c;只不过读写文件的接口略有不同&#xff0c;lua代码的处理是相同的。 下面两个方法是 LuaTable和字符串互相转换的代码 function XUtils.luaTableToString(tab, sp)sp sp or ""local s ""for k,v in pairs(tab) doif t…...

光伏业务管理系统的一些妙用功能

现在信息化流程化基本上每个行业都必须要有的了&#xff0c;光伏业务管理系统软件是一种专门用于光伏产业运营和管理的综合性系统&#xff0c;它结合了信息技术、数据分析、项目管理、客户管理等多个领域的知识&#xff0c;为光伏企业提供了一个全面、高效、智能的管理平台&…...

Java面试八股之请简述消息队列的发布订阅模式

请简述消息队列的发布订阅模式 发布订阅&#xff08;Publish-Subscribe&#xff0c;简称 Pub/Sub&#xff09;模型是一种消息传递模式&#xff0c;它在组件之间提供了高度的解耦和灵活性。这种模式广泛应用于分布式系统、事件驱动架构以及消息队列系统中。下面是发布订阅模型的…...

七、2 ADC数模转换器有关函数介绍(Keil5)

函数介绍 &#xff08;1&#xff09;ADCCLK的配置函数&#xff08;在rcc.h中&#xff09; &#xff08;2&#xff09;ADC的库函数&#xff08;在adc.h中&#xff09;...

了解载波侦听多路访问CSMA(上)

1.CSMA的思想 CSMA的全称是Carrier Sense Multiple Access&#xff0c;在笔者的理解中&#xff0c;其更趋向于一种理论研究的随机接入协议&#xff0c;或者说&#xff0c;基于其思想诞生了比如CSMA/CD与CSMA/CA这样的具体协议。CSMA可以分成以下三种&#xff1a; 1-persistent…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...