求和意义和性质
当一个算法包含循环控制结构时,例如while
或者for
循环,我们可以将算法的运行时间表示为每一次执行循环体所花时间之和。通过累加每次迭代所用时间,可以获得其和(或称级数)。
序号
在数学上,我们有一个求和序号——∑(英语名称: sigma,汉语名称:西格玛,是第十八个希腊字母)。
作用: 表示一系列数值的累加。
基本用法:
- 下标( ): 起始序号,表示求和变量的起始值
- 上标( ): 终止序号,表示求和变量的终止值。
- 待求和的项( )
例: 给定一个数列 ,其中n是非负整数,可以将有限和 写作: 并且: 让该数列无限延长( ),则有: 即:
当其极限不存在时,该级数1发散;反之,该级数收敛。对于收敛级数,不能随意对其项改变求和顺序。而对于绝对收敛级数(若对于级数有级数也收敛,则称其为绝对收敛级数),则可以改变其项的求和顺序。
性质
线性性质
对于求和,我们有下面的两个基本线性性质: 将两个综合起来就有: 对于任意实数和任意有限序列和,有 注: 线性性质对于无限收敛级数同样适用。线性性质可以用来对项中包含渐近记号的和式求和。
等差级数
等差数列的前项和称为一个等差级数2,也叫算术级数。常见的有: 用高斯求和,得
编程中使用
pub fn sigma_sum(start: i32, end: i32, f: impl Fn(i32) -> i32) -> i32 {
// 这里利用rayon还可以并行计算,对大数据很有用
(start..=end) // 生成一个包含结束值(闭合)的迭代器
.map(f) // 对迭代器每一个项获取求和数据
.sum() // 完成求和
}
// example-test
sigma_sum(1, 5, |x| x * x) // 输出1 ^ 2 + 2 ^ 2 + 3 ^ 2 + 4 ^ 2 + 5 ^ 2的和
对于算术级数可以利用高斯求和,时间复杂度从降低到:
pub fn gauss_sum(start: i64, end: i64) -> i64 {
// 先除后乘,防止中间溢出
if (start + end) % 2 == 0 {
(start + end) / 2 * (end - start + 1)
} else {
(end - start + 1) / 2 * (start + end)
}
}