一道面试题作为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次总速度与总平均速度的比较,这样可以省去计算平均速度除法带来的开销。