【问题标题】:How can I average a subset of an array and store the result in another array?如何平均一个数组的子集并将结果存储在另一个数组中?
【发布时间】:2011-10-18 01:24:57
【问题描述】:

我有一个 C 数组 fftArray[64],其中包含我想要平均并放入另一个数组 frequencyBar[8] 的值。使用 for 语句获得整个数组的平均值很容易。

int average, sum = 0;
for (i = 0; i < 64; i++)
{
     sum += fftArray[i];
}
average = sum/64;

但我似乎无法弄清楚如何从fftArray[0]fftArray[8] 中获取平均值并将其存储在frequencyBar[0] 中,fftArray[9]fftArray[16] 的平均值并将其存储在@987654329 中@等。有人可以帮我解决这个问题吗?谢谢

【问题讨论】:

    标签: c arrays math arduino average


    【解决方案1】:

    这看起来像是一个家庭作业,所以,与其给你直接的答案,我宁愿给你指出正确的方向......

    使用嵌套循环(一个在另一个里面)。一个循环循环 0-7,另一个循环 0-63。使用较小的循环填充切片平均值。

    或者更好的是使用 % 运算符来查看您何时遍历了 8 个元素并对总数求平均值,然后为下一组重置总数。然后,您也将学会如何使用 % 运算符! :)

    [编辑] 好吧,如果不是家庭作业,那就这样吧……我已经 5 年没有写过 C 语言了,所以把它当作伪代码:

    //assuming you have a fftArray[64] with data, as per your question
    int i,sum,avCounter,total;
    int averages[8]; 
    for(i=0 , avCounter=0, total=0 ; i<64; ){
        total += fftArray[i];
        if(++i % 8 == 0){   //%gives you the remainder which will be 0 every 8th cycle
          averages[avCounter++] = total / 8
          total = 0;  //reset for next cycle
        }
    }
    

    我认为这会比嵌套循环更好......但我不确定,因为 % 是除法,它比加法更重处理器......但是......我怀疑有人会注意到 :)

    【讨论】:

    • 我将它与我的 Arduino 和 FFT 库一起使用,从音频信号中提取频率量以创建 Arduino 音乐可视化器。感谢您的建议
    • 感谢 Dr. Dredel。我会试试这个和一个嵌套语句,看看哪个更快。巧妙地使用 %!
    • 如果您将i 的类型更改为unsigned,那么编译器将能够使用逻辑与而不是除法来执行i % 8
    【解决方案2】:
    int i, j;
    for (i = 0; i < 8; i++) {
        int sum = 0;
        for (j = 0; j < 8; j++) {
            sum += fftArray[ 8*i + j ];
        }
        frequencyBar[i] = sum / 8;
    }
    

    奖励练习:在您选择的平台上优化此代码以提高速度。

    【讨论】:

    • 谢谢,看起来像我需要的。而且我会尝试从中榨取每一盎司的性能,因为 FFT 算法从我的小 Arduino 中提取了很多东西!
    【解决方案3】:

    TF,

    免责声明:这段代码只是在我脑海中浮现......它甚至还没有被编译,更不用说测试了。

    // returns the average of array[first..last] inclusive.
    int average(int[] array, int first, int last) {
        int sum = 0; 
        for (i = first; i <= last; i++)
            sum += array[i];
        return sum / (last - first + 1); // not sure about the +1
    }
    

    然后你要做的是遍历你的frequencyBar数组[0..7]的索引,设置frequencyBar[i] = average(array, first, last);...棘手的一点是计算firstlast索引。 . 分别尝试i*8(i+1)*8...这可能不完全正确,但它会很接近;-)

    干杯。基思。


    编辑:无聊...等待我的测试结果回来。没有消息就是好消息,对吧? ;-)

    事实证明,传递length 比传递last 索引要简单一些。

    #include <stdio.h>
    
    int sum(int array[], int first, int length) {
        int sum = 0;
        for (int i = first; i < first+length; i++)
            sum += array[i];
        return sum;
    } 
    
    double average(int array[], int first, int length) {
        double total = sum(array, first, length);
    #ifdef DEBUG
        printf("DEBUG: [%2d..%2d] %d", first, first+length-1, array[first]);
        for (int i = first+1; i < first+length; i++)
            printf(" + %d", array[i]);
        printf(" = %d / %d = %f\n", (int)total, length, total/length);
    #endif
        return total / length;
    } 
    
    int main(int argc, char* argv[]) {
        int array[] = {             // average
            1, 2, 3, 4, 5, 1, 2, 3, // 2.625 
            4, 5, 1, 2, 3, 4, 5, 1, // 3.125 
            2, 3, 4, 5, 1, 2, 3, 4, // 3
            5, 1, 2, 3, 4, 5, 1, 2, // 2.875
            3, 4, 5, 1, 2, 3, 4, 5, // 3.375
            1, 2, 3, 4, 5, 1, 2, 3, // 2.625
            4, 5, 1, 2, 3, 4, 5, 1, // 3.125
            2, 3, 4, 5, 1, 2, 3, 4  // 3
        };
        double frequency[8];
        for (int i = 0; i < 8; i++)
            frequency[i] = average(array, i*8, 8);
    
        for (int i = 0; i < 8; i++)
            printf("%f ", frequency[i]);
        printf("\n");
    }
    

    【讨论】:

      【解决方案4】:

      如果fftArray 具有很大的价值,请注意您的sum 不会环绕!

      【讨论】:

        猜你喜欢
        • 2017-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2016-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多