一道面试题作为blog的开头

题目:200ms获取一次汽车当前行驶速度,计算30S内平均速度,若超过100KM/S,则开始报警,否则停止报警。设计一个函数供其他人调用,要求效率尽可能的高。
思考了一下,这个函数应该是在一个定时器中断服务函数中调用的,可能影响效率的只有求平均速度这一点,因为可能用到除法。我给出的答案如下:

 1 /*! 200ms获取一次当前行驶速度,计算30秒内平均速度,若超过100km/s 则报警,否则停止报警 */
 2 #define SPEED_INVERVAL          200                         // 获取当前速度的间隔
 3 #define SPEED_TIME              30*1000                     // 计算平均速度要统计的总时间
 4 #define SPEED_NR                (SPEED_TIME/SPEED_INVERVAL) // 计算平均速度要统计的速度次数
 5 #define AVERAGE_SPEED           100                         // 报警速度
 6 #define TOTAL_SPEEDS            (AVERAGE_SPEED*SPEED_NR)    // 报警总速度
 7 
 8 static int speeds[SPEED_NR];                                /* 当前速度*/
 9 static int index = 0;                                       /* 当前速度要存储的位置索引*/
10 static int count = 0;                                       /* 已计算平均速度次数*/
11 static int TotalSpeed = 0;                                  /* 当前总速度*/
12 
13 extern void BeepStart(void);                                /* 开始报警 */
14 extern void BeepStop(void);                                 /* 停止报警*/
15 
16 /*! 计算平均速度,若超过平均速度则开始报警,否则停止报警*/
17 void CheckSpeed(int CurSpeed)
18 {
19     if(count<SPEED_NR){                                     /* 计算总速度*/
20         TotalSpeed += CurSpeed;
21         speeds[index] = CurSpeed;
22     }else{
23         TotalSpeed = TotalSpeed-speeds[index]+CurSpeed;
24         speeds[index] = CurSpeed;
25     }
26 
27     if(++index == SPEED_NR){
28         index = 0;
29     }
30     if(TotalSpeed >= TOTAL_SPEEDS){                         /* 判断总速度是否超过报警总速度*/
31         BeepStart();
32     }else{
33         BeepStop();
34     }
35 }

知识点:
1.用了一个数组做循环队列,保存最近的30×1000/200=150次速度,这样就简化了平均速度的计算。

2.把平均速度的比较转化成最近150次总速度与总平均速度的比较,这样可以省去计算平均速度除法带来的开销。

posted @ 2014-03-19 10:14  云动随心  阅读(146)  评论(0编辑  收藏  举报