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

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

相关

源码测试用例下载

https://download.csdn.net/download/he_zhidan/88430716 包括4个压缩包,初始代码,实现前缀和,实现前缀积,实现前缀异或。都是在前者的基础上修改的。

本博文是CSDN学院课程的讲义

https://edu.csdn.net/course/detail/38771

前缀和(前缀积、前缀异或)应用的博文

C++前缀和算法的应用:DI序列的有效排列

C++前缀和算法应用:和至少为 K 的最短子数组

C++算法前缀和的应用:得分最高的最小轮调的原理、源码及测试用例

C++算法前缀和的应用:分割数组的最大值的原理、源码及测试用例

C++前缀和算法应用:矩形区域不超过 K 的最大数值和

C++前缀和算法:构造乘积矩阵

原理

长度为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

相关文章
|
2天前
|
算法 数据中心 C++
基于C++雪花算法工具类Snowflake -来自chatGPT
基于C++雪花算法工具类Snowflake -来自chatGPT
7 1
|
5天前
|
编译器 C++
C++的前缀++与后缀++是什么
C++的前缀++与后缀++是什么
|
7天前
|
算法 数据处理 C++
C++一分钟之-迭代器与算法
【6月更文挑战第21天】C++ STL的迭代器统一了容器元素访问,分为多种类型,如输入、输出、前向、双向和随机访问。迭代器使用时需留意失效和类型匹配。STL算法如查找、排序、复制要求特定类型的迭代器,注意容器兼容性和返回值处理。适配器和算法组合增强灵活性,但过度使用可能降低代码可读性。掌握迭代器和算法能提升编程效率和代码质量。
23 3
|
11天前
|
算法 前端开发 Linux
【常用技巧】C++ STL容器操作:6种常用场景算法
STL在Linux C++中使用的非常普遍,掌握并合适的使用各种容器至关重要!
38 10
|
2天前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
11 0
|
4天前
|
算法 前端开发 安全
C++算法模板
C++算法模板
6 0
|
安全 Java 测试技术
python接口自动化(三)--如何设计接口测试用例(详解)
上篇我们已经介绍了什么是接口测试和接口测试的意义。在开始接口测试之前,我们来想一下,如何进行接口测试的准备工作。或者说,接口测试的流程是什么?有些人就很好奇,接口测试要流程干嘛?不就是拿着接口文档直接利用接口 测试工具测试嘛。其实,如果只是三五个接口,你可以这么做一个临时的接口测试。但是,如果是上百个接口,或者,你们公司的这个项目,第一次做接口测试,那么,我们还是很有必要严格遵守接口测试的流程。
313 0
python接口自动化(三)--如何设计接口测试用例(详解)
|
测试技术
正交试验测试用例设计及工具推荐
在科研和生产实践中,人们往往要做许多次实验来进行某项研究。实验条件一般包括很多因素,当因素的值不同时,实验的结果也不一样。如果想把每个因素的每个值都要实验一遍,总实验数就等于各因素的值的个数的乘积,而这个数往往很大,超过了可接受的成本。 例如,假设某个实验由A,B,C,D四个因素,每个因素都有10个不同的取值,那么如果想把每个因素都考虑到,我们需要做 10*10*10*10=10000次实验。 为了减少实验数目,我们必须选出那些最有代表性的例子。于是,就要用到了正交表法(Orthogonal Array Testing Strategy)。
273 0
正交试验测试用例设计及工具推荐
|
测试技术 数据库 数据安全/隐私保护
测试用例设计之业务流程分析法
测试用例设计之业务流程分析法
227 0
测试用例设计之业务流程分析法
|
算法 Java 测试技术
边界值分析法测试用例设计实例
边界值分析法是黑盒测试的重要方法,本文以一道数位DP算法题为例,自主测试黑盒测试用例,并采用JUnit5完成单元测试。
156 0