【发布时间】:2021-01-25 04:08:54
【问题描述】:
问题 1:假设您有一个包含 n 个浮点数的数组,并且您想要计算一个包含三个元素的 n 个运行平均值的数组。中间部分很简单:
for (int i=0; i<n; i++)
b[i] = (a[i-1] + a[i] + a[i+1])/3.
但是您需要有单独的代码来处理i==0 和i==(n-1) 的情况。这通常通过循环前的额外代码、循环后的额外代码以及调整循环范围来完成,例如
b[0] = (a[0] + a[1])/2.
for (int i=1; i<n-1; i++)
b[i] = (a[i-1] + a[i] + a[i+1])/3.;
b[n-1] = (a[n-1] + a[n-2])/2.
即使这样还不够,因为n
问题 2。您正在从数组中读取可变长度代码(例如实现 UTF-8 到 UTF-32 转换器)。代码读取一个字节,因此可以读取一个或多个字节以确定输出。但是,在每个这样的步骤之前,它还需要检查是否已到达输入数组的末尾,如果已到达,则可能将更多数据加载到缓冲区中,或者以错误终止。
这两个问题都是循环的情况,循环的内部可以整齐地表达,但边缘需要特殊处理。我发现这类问题最容易出错和混乱的编程。所以这是我的问题: 是否有任何 C++ 习语可以概括以干净的方式包装此类循环模式?
【问题讨论】:
-
最简单的方法是移动(非运行)平均值数组的元素少于输入(考虑到在边缘,您无法使用相同的方法计算平均值元素的数量 - 所以不要计算它们)。如果您需要平均值数组具有相同数量的元素,则需要对被平均数据的性质做出一些假设。
-
这是几种可能的解决方案之一(例如,您也可以通过多种方式填充数组),但这只是一个简单的示例。我正在寻找解决此类问题的通用方法。
-
@Zzyzx - 没有针对此类问题的通用方法。是的,有几种方式可以使用填充。在计算移动平均值之前,也可以使用某种形式的过滤。所有方法都涉及对输入数据(或生成它的过程)的特征做出一些假设。但是没有适用于所有情况的通用/通用方法。
-
当然。我希望以某种方式以清晰的方式封装边缘行为,同时最大限度地减少索引计算错误的可能性,并生成高效的代码。
-
我在想
range的一些概括,这将允许“假”迭代器超出实际现有元素。
标签: c++ loops for-loop design-patterns