对《模拟管道算法的一次实际应用》一文的思考和改进

刚才刷手机看到今天脚本之家推送的一个文章《模拟管道算法的一次实际应用》  地址   https://mp.weixin.qq.com/s/89VfbuuB3Yz8sQFv2JwMYA  

作者对问题的描述是 “”“

  前段时间从事单片机开发的同学找我帮忙解决一个问题:有一个数据采集的设备,该设备定时对外进行数据采集。当数据采集小于5份时,记住所有的数据,并求和;

当数据采集超过5份时,只记住最近采集到的5份,并求和。

”“”

作者使用了顺序前移法,每次向后插入一个数据都需要把n-1个数据向前移动一次。那么问题来了,对于单片机来说其速度是硬伤(虽然也占用不了多少时间),可是总还是不优雅。此外,

如果对于具有1000个数据的情形是否还能这样靠移动呢? 分析一下这样移动的时间复杂度就是O(n)。

其实,我们还有更好的方法,可以让时间复杂度成为O(1)。使用什么方法呢,当然使用指针,移动指针,代码清晰简单,也无需过多解释:

 

#include <iostream>
using namespace std;

static const uint16_t DATALENGTH=5;  //数据长度
static uint16_t datalist[DATALENGTH]={0};
static uint16_t *currentdata=datalist;
//这里当成一个圈,从头开始插入,当最后一个插入后,下一次从头再来
void adddata(uint16_t dt) {
    *currentdata++=dt;
    if (currentdata==datalist+DATALENGTH) currentdata=datalist;   //这里就是负责当插入的指针到末尾后,跳回到前面
}

void printdata()
{
    for (int i=0;i<DATALENGTH;i++){
        cout<<datalist[i]<<'\t';
    }
    cout<<endl;
}

void calsum() {
    uint32_t sum=0;
    for (int i=0;i<DATALENGTH;i++){
        sum+=datalist[i];
    }
    cout<<"The sum of sensor is :"<<sum <<endl;

}
int main()
{
    uint16_t dt;
    while(1) {
        printdata();
        cin>>dt;
        adddata(dt);
        calsum();
    }
    return 0;
}

 输出:

0       0       0       0       0
1
The sum of sensor is :1
1       0       0       0       0
2
The sum of sensor is :3
1       2       0       0       0
3
The sum of sensor is :6
1       2       3       0       0
4
The sum of sensor is :10
1       2       3       4       0
5
The sum of sensor is :15
1       2       3       4       5
6
The sum of sensor is :20
6       2       3       4       5
7
The sum of sensor is :25
6       7       3       4       5
8
The sum of sensor is :30
6       7       8       4       5
9
The sum of sensor is :35
6       7       8       9       5
0
The sum of sensor is :30
6       7       8       9       0

这不是更清晰简单吗?

这里我想说的是,作者的想法没有问题但是如果数据很长的话,那就不是一个好的方法了。

我们有时候需要对问题真的做好分析,找到那个hit point。

不要说我太mean,有时候需要较较真。这个方法可能我自己也要使用。

看到数据结构,就是个头尾相接的链表,总之,这是一个数据结构问题。

还有,一般加和是不怎么用的,需要滤波是真的,中值滤波可以考虑下。

当然本文的算法即使数据长度修改为1000,10000。 插入新的数据仍然嗖的一下。因为时间复杂度是O(1)。

 

如果使用Python 那就更简单了。直接使用:

from collections import deque

dt=deque(maxlen=5)   #maxlen指的是长度

dt.append(1)    #向右添加元素

dt.append(2)

dt.append(3)

dt.append(4)

dt.append(5)

deque([1, 2, 3, 4, 5], maxlen=5)

dt.append(6)

deque([2, 3, 4, 5, 6], maxlen=5) 

python还是很神奇。

 

 

 

 

posted on 2019-08-04 20:38  看看完了  阅读(241)  评论(0编辑  收藏  举报

导航