代码挑战:如何简化指定起始索引取指定长度数组元素的代码
简化代码提升可读性的方案
嘿,我来帮你简化这段代码!先理清楚你的需求:生成一个长度为n的数组,前signature.Length个元素用给定的signature填充,之后每个元素都是它前面signature.Length个元素的总和。原代码功能没问题,但确实可以更简洁易读,我们一步步来优化:
核心优化点
1. 简化数组初始化
原代码手动给ret的前几个元素赋值,这种写法不仅冗长,还无法适配signature长度变化的情况。我们可以用Array.Copy一次性完成初始化:
double[] ret = new double[n]; Array.Copy(signature, ret, signature.Length);
不管signature是3个元素还是其他长度,这行代码都能自动把signature的内容复制到ret的前对应位置。
2. 替换嵌套循环,维护滚动总和
原代码用嵌套循环每次重新计算总和,既浪费性能(时间复杂度O(n*k),k是signature长度),也让代码更复杂。我们可以维护一个滚动的总和:
- 初始总和是
signature所有元素的和 - 每生成一个新元素,这个元素的值就是当前总和
- 更新总和时,只需要加上新元素,再减去
signatureLength步之前的那个元素(因为它已经移出了“前k个元素”的窗口)
这样把时间复杂度降到O(n),代码也更简洁。
3. 优化变量命名与作用域
原代码的变量x、i提前声明在外部作用域,变量名也不够直观。优化后我们:
- 在循环内部声明循环变量
i,缩小作用域 - 用
signatureLength代替重复的signature.Length,用currentSum代替模糊的sum,让变量含义一目了然
优化后的完整代码
int n = 10; double[] signature = new double[] { 1, 1, 1 }; int signatureLength = signature.Length; double[] ret = new double[n]; // 初始化结果数组的前signatureLength个元素 Array.Copy(signature, ret, signatureLength); // 计算初始总和(如果不想用LINQ,可替换为手动循环求和) double currentSum = signature.Sum(); // 生成后续元素 for (int i = signatureLength; i < n; i++) { ret[i] = currentSum; // 更新滚动总和:加入新元素,移除窗口最左侧的旧元素 currentSum += ret[i] - ret[i - signatureLength]; } return ret;
替代方案(不用LINQ求和)
如果项目中不允许使用LINQ,手动计算初始总和也很简单:
double currentSum = 0; foreach (double num in signature) { currentSum += num; }
这样优化后的代码结构清晰,逻辑直观,同时性能也比原代码更好,还能适配任意长度的signature。
内容的提问来源于stack exchange,提问作者Keith
相关产品推荐
相关产品推荐

