C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例

news2025/1/11 21:43:36

相关

源码测试用例下载
https://download.csdn.net/download/he_zhidan/88430716 包括4个压缩包,初始代码,实现前缀和,实现前缀积,实现前缀异或。都是在前者的基础上修改的。
本博文是CSDN学院课程的讲义
https://edu.csdn.net/course/detail/38771

前缀和(前缀积、前缀异或)应用的博文
C++前缀和算法:构造乘积矩阵
C++前缀和算法应用:矩形区域不超过 K 的最大数值和

原理

长度为n的数组nums,共有n+1个以nums[0]开始的子数组。索引范围分别为[0,i),i取值区间[0,n]。preSum[i]记录子数组[0,i)的和。比如:nums = {1,2,3,4},则preSum = {0,1,3,6,10}。通过preSum,我们可以求任意nums的子数组和。子数组[i,j)等于子数组[0,j)减去[0,i),也就是子数组[i,j)的和等于preSum[j] – preSum[i]。如果i等于j,则preSum[i]-preSum[i],和为0,符合计算公式。如果i大于j,则非法,需要提前排除。

暴力法

时间复杂度O(n*n)。

核心代码

class CPreSum
{
public:
//左闭右开空间
long long SumO2(int left, int r)
{
long long llRet = 0;
for (; left < r; left++)
{
llRet += m_sums[left];
}
return llRet;
}
vector m_sums;
};

测试代码

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

void Test1()
{
CPreSum preSum;
preSum.m_sums = { 1,2,3,4 };
vector ans = { 0,1,3,6,10 };
auto res = preSum.SumO2(0, 4);
Assert(10LL, res);
res = preSum.SumO2(0, 3);
Assert(6LL, res);
res = preSum.SumO2(0, 2);
Assert(3LL, res);
res = preSum.SumO2(0, 1);
Assert(1LL, res);
res = preSum.SumO2(0, 0);
Assert(0LL, res);
res = preSum.SumO2(1, 4);
Assert(9LL, res);
res = preSum.SumO2(1, 3);
Assert(5LL, res);
}

void Test2()
{
srand(time(nullptr));
int n = rand() % 10 + 1;
CPreSum preSum;
for (int i = 0; i < n; i++)
{
preSum.m_sums.emplace_back(rand() % 10000);
}
preSum.Init();
for (int left = 0; left < n; left++)
{
for (int r = left; r <= n; r++)
{
long long res1 = preSum.SumO1(left, r);
long long res2 = preSum.SumO2(left, r);
assert(res1==res2);
}
}
}
int main()
{
Test1();
Test2();
}

前缀和

时间复杂度O(n),预处理O(n),每次查询O(1)。

代码

void Init()
{
m_vPreSum.emplace_back(0);
for (const auto& n : m_nums)
{
m_vPreSum.emplace_back(n + m_vPreSum.back());
}
}
long long SumO1(int left, int r)
{
return m_vPreSum[r] - m_vPreSum[left];
}
vector m_vPreSum;

前缀乘积

只需要修改三处m_vPreSum[0]=1,+变成*,-变成除。

修改后的代码

class CPreSum
{
public:
//左闭右开空间
long long SumO2(int left, int r)
{
long long llRet = 1;
for (; left < r; left++)
{
llRet *= m_nums[left];
}
return llRet;
}
void Init()
{
m_vPreSum.emplace_back(1);
for (const auto& n : m_nums)
{
m_vPreSum.emplace_back(n * m_vPreSum.back());
}
}
long long SumO1(int left, int r)
{
return m_vPreSum[r] / m_vPreSum[left];
}
vector m_vPreSum;
vector m_nums;

};

前缀异或

C语言异或的符合是,初始0,也就是m_vPreSum.emplace_back(0)。异或的逆运算是本身,所以乘除都换成

其它

视频课程

要是你认为本篇难道较大,不好入手,推荐你先学习基础算法的课程,我已完成部分,余下部分持续更新中,就在CSDN学院。
https://edu.csdn.net/course/detail/38771

C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17

相关下载

如果你想观其大略,建设下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

博主想队大家说的话
墨家名称的来源:有所得以墨记之。
闻缺陷则喜的来由:早发现,早修改问题,成本更低
程序是龙,算法是睛

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

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

相关文章

记录--P0事故预警

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 背景 某一天&#xff0c;前端小余同学和后端别问我小哥在做登录业务接口对接&#xff0c;出于业务的特殊性和安全性的考虑&#xff0c;她和后端小哥约定“user”相关信息参数需要通过HTTP协议的header…

Elastic Stack 和 Docker Compose 入门:第 2 部分

作者&#xff1a;Eddie Mitchell 欢迎阅读 Elastic Stack 和 Docker Compose 入门的第二部分。 在第一部分博客中&#xff0c;我们了解了 Docker Compose 的基础知识以及如何将单节点集群建立为本地游乐场&#xff0c;其中包括 Elasticsearch、Kibana、Logstash、Metricbeat 和…

JVS-rules规则引擎,解决大数据风控的自动化决策利器

规则引擎中的评分卡节点是一种用于评估客户信用、风险等级或其他指标的重要工具。它通常用于金融、信贷等领域&#xff0c;以便根据一系列预定义的规则和权重来对客户进行评分。以下是评分卡节点的主要功能、作用以及配置方式的介绍&#xff1a; 功能和作用&#xff1a; 评估…

BUUCTF学习(5): 命令执行Ping

1、介绍 2、解题 127.0.0.1|cat /flag 结束

第三章 交换技术及应用

3.1 port-vlan技术 3.1.1 VLAN概述 VLAN(Virtual Local Area Network)&#xff0c;虚拟局域网VLAN是在一个已建好的物理网络上划分出来的逻辑网络。作用&#xff1a;隔离广播域&#xff0c;同一个VLAN主机可以通信而不同VLAN不能通信。 3.1.2 VLAN划分方法——Port-VLAN 基于端…

ArcGIS笔记7_如何创建新的shp要素文件?新shp的坐标系选择?

本文目录 前言Step 1 创建新的shp要素文件的操作Step 2 常用的坐标系选择Step 3 有点笨但好用的新建shp要素的方法 前言 很多ArcGIS新手都会遇到的问题&#xff0c;会编辑现成的shp要素文件&#xff0c;但不会创建新shp&#xff0c;而且创建时需要选择新的坐标系&#xff0c;这…

OpenSIPS 防扫描处理

文章目录 1. 问题背景2. 防范处理2.1 IP 封禁2.2 OpenSIPS 处理2.2.1 REGISTER 请求2.2.2 INVITE 请求 1. 问题背景 OpenSIPS 作为 SIP 注册服务器&#xff0c;通常需要放在公网供公司各地的员工使用&#xff0c;但是这样就会产生外部扫描问题。一般来说外部扫描量不会很大&am…

ElasticSearch-数据查询

ElasticSearch-数据查询 目录概述需求&#xff1a; 设计思路实现思路分析1.查询某索引下的所有数据2.二、条件查询3.、条件查询方式二4.四、分页查询5.五、格式化数据 六、排序七 其他条件执行的成立的查询九、范围查询 参考资料和推荐阅读 Survive by day and develop by nigh…

13-k8s-ingress网络

文章目录 一、ingress介绍二、创建nginx和tomcat供测试三、创建ingress-http四、yaml方式安装ingress五、helm方式安装ingress&#xff08;推荐&#xff09;六、Ingress的HTTPS代理 一、ingress介绍 Service对集群之外暴露服务的主要方式有两种&#xff1a;NotePort和LoadBalan…

强化学习基础(2)—常用算法总结

目录 1.Value-Based 2. Policy-Based 参考文献 1.Value-Based Sarsa&#xff08;State-action-reward-state’-action&#xff09;&#xff1a;是为了建立和优化状态-动作(state-action)的价值Q表格所建立的方法。首先初始化Q表格&#xff0c;根据当前的状态和动作与环境进行…

Mapping 设计指南

Mapping 设计指南 目录概述需求&#xff1a; 设计思路实现思路分析1、properties2.fields 3.search_analyzer4.2、format1、enabled2、doc_values 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0…

数据库、数据中台、数据仓库、数据湖区别

数据时代&#xff0c;各行业的企业都已经开始通过数据库来沉淀数据&#xff0c;但是真的论起数据库、数据仓库、数据中台&#xff0c;还是新出现的数据湖&#xff0c;它们的概念和区别&#xff0c;可能知道的人就比较少了&#xff0c;今天我们详细来比较了解一下。 一、数据仓…

FPGA通过读写突发对DS1302时钟的配置驱动

文章目录 前言一、pandas是什么&#xff1f;1、理论原理1、DS1302实时时钟芯片1、特性2、引脚定义3、有关读写操作的详细内容1、读写的几个端口信号2、命令字节3、突发读写时钟寄存器4、写保护位 4、数据读写时序&寄存器地址表1、数据单字节读写时序2、寄存器地址表 5、数据…

✔ ★【备战实习(面经+项目+算法)】 10.16学习时间表(总计学习时间:5h)

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…

C++指针解读(10)-- 动态内存分配

栈和堆是进程内存空间中非常重要的2块区域。栈用于存放程序临时创建的局部变量&#xff1b;堆用于存放进程运行中被动态分配的内存段。当进程调用malloc等函数分配内存时&#xff0c;新分配的内存就被动态添加到堆上&#xff1b;当利用free等函数释放内存时&#xff0c;被释放的…

虚拟机和Windows共享文件的几种方式(共享文件夹、网络映射、Winscp)

1、共享文件夹 在虚拟机的“/mnt/hgfs/”目录下能看到和Windows共享的文件&#xff1b; 2、网络映射 2.1、安装samba服务器 #安装samba服务器 apt-get install samba samba-common#添加samba账户 smbpasswd -a ckl passwd:1232.2、设置网络映射 3、Winscp共享文件 3.1、Wins…

snk-给github界面加一个有趣的动画

How to enable GitHub Actions on your Profile README for a snake-eating contribution graph &#x1f40d; - DEV Community Platane/Platane (github.com) ① 创建New repository 名字和你自己的Github 用户名一样。 ② 创建之后&#xff0c;再这个Zero-coder仓库下创建…

[C国演义] 第十五章

第十五章 最长湍流子数组环绕字符串中唯⼀的⼦字符串 最长湍流子数组 力扣链接 子数组 ⇒ dp[i]的含义: 以arr[i] 结尾的所有子数组中的最长湍流子数组的长度 子数组 ⇒ 状态转移方程根据 最后一个位置来划分&#x1f447;&#x1f447;&#x1f447; 初始化: 都初始化为…

任务调度框架-如何实现定时任务+RabbitMQ事务+手动ACK

任务调度框架 Java中如何实现定时任务&#xff1f; 比如&#xff1a; 1.每天早上6点定时执行 2.每月最后一个工作日&#xff0c;考勤统计 3.每个月25号信用卡还款 4.会员生日祝福 5.每隔3秒&#xff0c;自动提醒 10分钟的超时订单的自动取消&#xff0c;每隔30秒或1分钟查询…

Gson反序列化原理

前言 序列化和反序列化是日常工作中经常使用的工具&#xff0c;一般用于对象的持久化保存或者对象的网络传输&#xff0c;一般有两种情况&#xff0c;一种是对象本身实现了Serializable接口&#xff0c;这种情况下可以利用jdk自带的功能或者Kryo等这种封装好的序列化反序列化工…