学习笔记那些有意思又好用的小算法
昔枫沐杰我认为再简单的算法,只要能解决实际问题,提高解决问题的效率,都是好算法。下面介绍一些有意思又好用的算法,希望对大家有所帮助。
1. 线性归一化
1.1 简介
线性归一化是一种常用的数据预处理方法,主要用于将数据缩放到一个特定的范围,通常是[0, 1]。在嵌入式中常用于ADC或其他类型传感器的数据处理,将获取到的待测数值 映射到[0%, 100%]之间,方便后续处理。
公式1:
X′=max−minX−min×100%
公式1中
X’:计算得到的归一化百分比结果
X:待测数值
min:标定的最小值
max:标定的最大值
以上公式1待测数值与结果是正比关系,即待测数值越大,结果百分比越大。但实际情况中,呈现反比关系的传感器并不少见,这时需要对公式1进行变形才能得到反比公式。反比关系无非就是计算100%-X’,即用100%减去正比的百分比结果,最后得到的就是反比结果,公式变形过程如下:
Y′=100%−X′
=100%−max−minX−min×100%
=max−min(max−min)−(X−min)×100%
最终得到公式2:
Y′=max−minmax−X×100%
公式2中
Y’:反比的百分比结果
1.2 代码演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <stdio.h>
typedef struct { int min; int max; int adc_value; float value_z; float value_f; } PERCENT;
void percent_computed(PERCENT *percent) { percent->value_z = (float)(percent->adc_value - percent->min) / (percent->max - percent->min) * 100; percent->value_f = (float)(percent->max - percent->adc_value) / (percent->max - percent->min) * 100; }
int main() { PERCENT percent = {0}; percent.min = 2000; percent.max = 3500; percent.adc_value = 2680;
percent_computed(&percent);
printf("value_z: %.2f%%\n", percent.value_z); printf("value_f: %.2f%%\n", percent.value_f);
return 0; }
|
2. 一阶低通
2.1 简介
一阶低通滤波器通常使用递归的方式来平滑信号。其基本形式可以表示为:
y[n]=αx[n]+(1−α)y[n−1]
其中:
y[n] 是当前输出,
x[n] 是当前输入,
alpha 是平滑因子(0 < alpha < 1),决定了滤波器的响应速度。
特点:
- 对高频噪声有较好的抑制效果。
- 适合处理连续信号。
- 计算简单,实时性强。
该算法通常用来处理不稳定的信号,使信号变得平滑。平滑因子需要根据实际情况设定,不宜过大也不宜过小,过大会导致效果大大减弱,而过小则太过于偏向于上一次输出的值,会增加输出迟滞性。
2.2 代码演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <stdio.h>
#define DATA_SIZE 10
int main() { int n; float alpha = 0.6; float raw_signal[DATA_SIZE] = {1.1, 1.4, 1.8, 2.6, 2.9, 3.7, 4.1, 4.4, 5.3, 5.5}; float filtered_signal[DATA_SIZE]; filtered_signal[0] = raw_signal[0];
for (n = 1; n < DATA_SIZE; n++) { filtered_signal[n] = alpha * raw_signal[n] + (1 - alpha) * filtered_signal[n - 1]; }
printf("时间点 | 原始信号 | 过滤后信号\n"); for (n = 0; n < DATA_SIZE; n++) { printf("%d | %.2f | %.2f\n", n, raw_signal[n], filtered_signal[n]); } return 0; }
|
编译,查看输出结果:
1 2 3 4 5 6 7 8 9 10 11 12
| PS E:\project\C_C++\adc> gcc t2.c -o t2; ./t2 时间点 | 原始信号 | 过滤后信号 0 | 1.10 | 1.10 1 | 1.40 | 1.28 2 | 1.80 | 1.59 3 | 2.60 | 2.20 4 | 2.90 | 2.62 5 | 3.70 | 3.27 6 | 4.10 | 3.77 7 | 4.40 | 4.15 8 | 5.30 | 4.84 9 | 5.50 | 5.24
|