C ++ - 计算"中的平均值"功能

时间:2018-03-18 20:29:19

标签: c++ for-loop

我试图为(forex)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] = ....
}

3 个答案:

答案 0 :(得分:1)

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

#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

当您使用无效参数调用它时,断言调用只会给您一个警告。当然,你也可以在没有功能的情况下实现这一目标。

std :: accumulate的文档:http://en.cppreference.com/w/cpp/algorithm/accumulate

答案 1 :(得分:1)

您不需要嵌套for循环。只需计算前缀总和(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的时间复杂度,这是很大的不同。

答案 2 :(得分:0)

cci_avg的最后一次调用正确地抛出了断言异常。该呼叫要求从索引3开始平均3个数字,即3,4和5。但是没有索引5.它们只有4个。

奖励:使用std :: accumulate。它每次都会得到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;
}