说明
- 数据集中度分析的目的是为了在一堆数据中找出有效的数据,数据集中度分析认为集中度越高的数据越可靠。
- 本文中的数据为模拟方式的随机生成,文中的某些部分是为了演示使用,实际项目中可去掉。
- 集中度分析是寻找与目标值在一定范围内的数据为有效数据。
一、 宏定义及数据类型定义
#ifndef u8
typedef unsigned char u8;
#endif
#ifndef u16
typedef unsigned short int u16;
#endif
#ifndef u32
typedef unsigned int u32;
#endif
#ifndef u64
typedef unsigned long long int u64;
#endif
#ifndef s8
typedef signed char s8;
#endif
#ifndef s16
typedef signed short int s16;
#endif
#ifndef s32
typedef signed int s32;
#endif
#ifndef s64
typedef signed long long int s64;
#endif
#define ABS2(x , y) ((x) > (y) ? (x) - (y) : (y) - (x))
#define DAT_SIZE (2000)
typedef struct
{
u16 Dat[DAT_SIZE];
u16 Count;
}DAT_TypeDef;
二、 获取平均值
u16 usGetDat_Average(DAT_TypeDef * pData)
{
u16 i = 0;
u32 sum = 0;
if (!pData->Count)
{
return 0;
}
for (i = 0; i < pData->Count; ++i)
{
sum += pData->Dat[i];
}
sum = (sum * 10) / pData->Count;
sum = (sum + 5) / 10;
return (u16)sum;
}
三、 生成随机数
/* 生成随机数 */
void vGeneration_Random_Number(u16 * pDat, u16 maxVal, u16 minVal, u16 num)
{
u16 i = 0;
u16 dat = 0;
u16 temp = 0;
temp = maxVal - minVal + 1;
srand(time(NULL));
for (i = 0; i < num; ++i)
{
dat = (u16)((rand() % temp) + minVal);
*(pDat + i) = dat;
}
}
四、数据集中度分析(不排序)
DAT_TypeDef ResDat = { 0 };
DAT_TypeDef MemDat = { 0 };
DAT_TypeDef * pResDat = &ResDat;
DAT_TypeDef * pMemDat = &MemDat;
/* 数据集中度分析(不排序) */
/* pDat : 分析的数据 */
/* len : 分析的数据长度 */
/* datGap : 有效数据范围 */
/* minCount : 最小集中度个数 */
u16 usConcentrate_Analyse_Unsorted(u16 * pDat, u16 len, u8 datGap, u8 minCount)
{
u16 i = 0, j = 0, k = 0;
u16 tmpDat = 0;
u16 initVal = 0;
u16 trueDat = 0;
u16 minDat = 0, maxDat = 0;
u16 maxCount = 0;
u16 seekCount = 0;
for (i = 0; i < len; ++i)
{
/* 找合法数据 */
trueDat = *(pDat + i);
if (!trueDat)
{
continue;
}
/* 清零参数 */
pMemDat->Count = initVal = 0;
minDat = 0xFFFF;
maxDat = 0;
for (j = 0; j < len; ++j)
{
/* 找合法数据 */
tmpDat = *(pDat + j);
if (!tmpDat)
{
continue;
}
/* 数据有效 */
if (ABS2(trueDat, tmpDat) <= datGap)
{
/* 保存初始数据 */
if (!pMemDat->Count)
{
initVal = trueDat;
}
/* 保存最值 */
if (maxDat < tmpDat)
{
maxDat = tmpDat;
}
if (minDat > tmpDat)
{
minDat = tmpDat;
}
/* 保存有效数据 */
pMemDat->Dat[pMemDat->Count++] = tmpDat;
}
}
/* 有效数据量少 */
if (pMemDat->Count < minCount)
{
continue;
}
printf("Analyse Succeed[%03u] Count:%-2u Init:%-5u Max:%-5u Min:%-5u ABS:%-5u AvgVal:%-5u\r\n", \
seekCount++, pMemDat->Count, initVal, maxDat, minDat, (maxDat - minDat), \
usGetDat_Average(pMemDat));
printf("[%u %u] ==> ", initVal, pMemDat->Count);
for (k = 0; k < pMemDat->Count; ++k)
{
if ((k) && (!(k % 12)))
{
printf("\r\n");
}
printf("%-5u ", pMemDat->Dat[k]);
}
printf("\r\n\r\n");
if (pMemDat->Count > maxCount)
{
/* 更新最大数量 */
maxCount = pResDat->Count = pMemDat->Count;
/* 将数据复制到结果缓存 */
for (k = 0; k < pMemDat->Count; ++k)
{
pResDat->Dat[k] = pMemDat->Dat[k];
}
/* 有效数据量过多提前退出 */
if (pMemDat->Count > ((len << 2) / 3))
{
return maxCount;
}
}
else if (pMemDat->Count == maxCount)
{
/* 认为平均值小的数据更可靠 */
if (usGetDat_Average(pResDat) > usGetDat_Average(pMemDat))
{
/* 将数据复制到结果缓存 */
for (k = 0; k < pMemDat->Count; ++k)
{
pResDat->Dat[k] = pMemDat->Dat[k];
}
}
}
}
return maxCount;
}
#五、演示例程
int main(int argc, char * argv[])
{
u16 xDat[100] = {0};
u16 len = sizeof(xDat) / sizeof(xDat[0]);
u16 i = 0;
vGeneration_Random_Number(xDat, 3000, 800, len);
printf("Original Data:\r\n");
for (i = 0; i < len; ++i)
{
if(i && ((i % 10) == 0))
{
printf("\r\n");
}
printf("[%03u]%-5u ", i, xDat[i]);
}
printf("\r\n\r\n");
i = usConcentrate_Analyse_Unsorted(xDat, len, 50, 10);
if (i)
{
printf("\r\n\r\n");
printf("Concentrate Analyse Succeed......Count:%-3u Avg:%u\r\n", pResDat->Count, usGetDat_Average(pResDat));
for (i = 0; i < pResDat->Count; ++i)
{
if (i && (!(i % 12)))
{
printf("\r\n");
}
printf("%-5u ", pResDat->Dat[i]);
}
}
else
{
printf("Concentrate Analyse Fail......\r\n");
}
printf("\r\n\r\n Compiler Date: %s %s\r\n", __DATE__, __TIME__);
while (1);
return 0;
}
五、运行结果