C++ - 计算"for"函数中的平均值

C++ - calculate average value in "for" function

本文关键字:平均值 函数 for 计算 C++      更新时间:2023-10-16

我正在尝试为(外汇(metatrader4平台(C++(创建自己的指标,但我在使用for函数时遇到了一个逻辑问题。

这是我代码的一部分

for(int i = limit - 1; i >= 0; i--) { 
   CCI_buffer[i] = iCCI(NULL,0,CCI_period,PRICE_WEIGHTED,i);
}

此代码将返回每个柱线(数组(的值。这很好。但我正在尝试计算最后 3 根(例如(柱线的平均值。

我想要实现的目标的一个实际例子。

(input values)
CCI_buffer[0] = 100
CCI_buffer[1] = 50
CCI_buffer[2] = 0
CCI_buffer[3] = 50
CCI_buffer[4] = 100

CCI_average[0] = (CCI_buffer[0] + CCI_buffer[1] + CCI_buffer[2]) / 3 ([0]= 50)
CCI_average[1] = (CCI_buffer[1] + CCI_buffer[2] + CCI_buffer[3]) / 3 ([1]= 33.33)
CCI_average[2] = (CCI_buffer[2] + CCI_buffer[3] + CCI_buffer[4]) / 3 ([2]= 50)

我该怎么做?在这种情况下,我的逻辑失败了(我可能是个傻瓜(,我需要向前推进。

我应该使用两次"FOR"功能吗?

for{
   for{
   }
}

还是我在公式中有"FOR"函数进行计算?

for {
   CCI_average[i] = ....
}

有两种方法解决任务的示例:

#include <iostream>
#include <cassert>
#include <numeric>
// Method 1
float cci_avg(int cci_buffer[], int index_start, int num_values, int size)
{
    assert(index_start+num_values <= size);
    assert(index_start >= 0);
    assert(num_values > 0);
    float sum = 0;
    for(int i=index_start; i < index_start+num_values; ++i)
    {
        sum += cci_buffer[i];
    }
    return sum/num_values;
}
int main() {
    const int SIZE = 5;
    int CCI_buffer[SIZE] = {100, 50, 0, 50, 100};
    // Call method 1
    std::cout << "0, 3: " << cci_avg(CCI_buffer, 0, 3, SIZE) << std::endl;
    std::cout << "1, 3: " << cci_avg(CCI_buffer, 1, 3, SIZE) << std::endl;
    std::cout << "2, 3: " << cci_avg(CCI_buffer, 2, 3, SIZE) << std::endl;
    // fails
    // std::cout << "3, 3: " << cci_avg(CCI_buffer, 3, 3, SIZE) << std::endl;
    // Method 2 with std::accumulate
    int num_values = 3;
    std::cout << "0, 3 with accumulate: " << std::accumulate(&CCI_buffer[0], &CCI_buffer[0+num_values], 0)/
                                             static_cast<float>(num_values) << std::endl;
    std::cout << "1, 3 with accumulate: " << std::accumulate(&CCI_buffer[1], &CCI_buffer[1+num_values], 0)/
                                             static_cast<float>(num_values) << std::endl;
    std::cout << "2, 3 with accumulate: " << std::accumulate(&CCI_buffer[2], &CCI_buffer[2+num_values], 0)/
                                             static_cast<float>(num_values) << std::endl;
    return 0;
}

输出:

0, 3: 50
1, 3: 33.3333
2, 3: 50
0, 3 with accumulate: 50
1, 3 with accumulate: 33.3333
2, 3 with accumulate: 50

断言调用只是在使用无效参数调用时发出警告。当然,您也可以在没有函数的情况下实现这一点。

标准文档::

累积:http://en.cppreference.com/w/cpp/algorithm/accumulate

你不需要嵌套的循环。只需计算前缀总和 (https://en.m.wikipedia.org/wiki/Prefix_sum(,
然后,您可以通过sums[last] - sums[first - 1]访问连续子序列的总和。
这将为您提供 O(n( 时间而不是 O(n*m((其中 n 是元素数,m 是计算平均值的元素数(在您的示例中为 3((。

如果你有 m=3,可以使用 O(n*m( 解,但如果 n=1000 和 m=1000,你会给出 10^6 而不是 10^3 的时间相容性,这是很大的差异。

cci_avg的最后一次调用会正确引发断言异常。调用要求平均从索引 3 开始的 3 个数字,即 3、4 和 5。但是没有索引 5。 他们只去 4。

奖励:使用标准::累积。它每次都会得到正确的 for 循环。

#include <iostream>
#include <numeric>
#include <cassert>
float cci_avg(int cci_buffer[], int index_start, int num_values, int size)
{
    assert(index_start+num_values <= size);
    assert(index_start >= 0);
    assert(num_values > 0);
    auto begin = cci_buffer+index_start;
    auto end = begin + num_values;
    return std::accumulate(begin, end, 0.0f) / num_values;
}
int main() {
    const int SIZE = 5;
    int CCI_buffer[SIZE];
    CCI_buffer[0] = 100;
    CCI_buffer[1] = 50;
    CCI_buffer[2] = 0;
    CCI_buffer[3] = 50;
    CCI_buffer[4] = 100;
    std::cout << "0, 3: " << cci_avg(CCI_buffer, 0, 3, SIZE) << std::endl;
    std::cout << "1, 3: " << cci_avg(CCI_buffer, 1, 3, SIZE) << std::endl;
    std::cout << "2, 3: " << cci_avg(CCI_buffer, 2, 3, SIZE) << std::endl;
    // The next is no good
   // std::cout << "3, 3: " << cci_avg(CCI_buffer, 3, 3, SIZE) << std::endl;
    return 0;
}