公司有一个检测系统,在单位时间内将每次检测结果保存。由于检测的环境受到外界干扰,会随机地出现异常值。以前的办法是:取得所有检测结果的最大值作为最终值。由于异常值的出现,导致检测结果非常不准确。于是思考在整个检测结果曲线中,取分布最密集的部分作为结果。(如果异常值大大多于正常值,且异常值的出现范围相同,则这种方法也不可靠。好在正常值是大多数)
算法实现的原理为:将N个数排序,从第一个数开始累加,然后除以个数得到n个数以来平均值,把平均值和当前的数比较,如果范围超出一个阈值,则认为后面的数属于下一个段,然后重新从当前数开始累加比较。遍历完成后就可以把整段数据分成若干个段,段以内的数值的变化都是比较小的。
在遍历中记录下每个段的长度,就可以得出数据最多的段,此段就是分布最密集的地方。把此段的值取平均就得到了检测中的正常值。
算法的源码如下:
#include <stdio.h>
#include <string.h>
int Data[] = ...{2, 7, 8, 20, 23, 25, 26, 32, 37, 38, 44, 52, 67, 69, 69, 72, 81, 88, 88, 92};
//段的阈值,决定数值变化的大小
const int RANGE = 3;
void ShowSection(int Data[], int Count) //显示数组中每个数据的分段结果
...{
int* Sec = new int[Count]; //记录段的编号
int nSum = 0;
int nCount = 0;
int nSection = 0;
int nAvg;
for (int i=0; i<Count; i++)
...{
nSum += Data[i];
nCount++;
nAvg = nSum/nCount; //取平均值
if (!(nAvg+RANGE>=Data[i] && nAvg-RANGE<=Data[i])) //如果当前值超过平均值的一定范围,则开始下一个段
...{
nSum = Data[i];
nCount = 1;
nSection++;
}
Sec[i] = nSection;
}
//打印
for (int i=0; i<Count; i++)
...{
printf("%d %d ", Data[i], Sec[i]);
}
delete[] Sec;
Sec = NULL;
}
//获得最大段的平均值
void ShowSection1(int Data[], int Count)
...{
int nSum = 0;
int nCount = 0;
int nSection = 0;
int nAvg;
int nMaxSection = 0; //最密集的段的ID
int nMaxSectionCount = 0; //最密集的段的元素个数
int nResult = 0; //计算后得出的平均值
int nIndex = -1; //段结束的下标
for (int i=0; i<Count; i++)
...{
nSum += Data[i];
nCount++;
nAvg = nSum/nCount;
if (!(nAvg+RANGE>=Data[i] && nAvg-RANGE<=Data[i]))
...{
if (nCount-1>nMaxSectionCount) //如果当前段比上一个段还大,则当前段设置成最大段
//如果存在多个数量相同的最大段,则使用大于取最后一个最大段,使用大于等于取第一个最大段
...{
nMaxSectionCount = nCount -1;
nMaxSection = nSection;
nResult = (nSum - Data[i])/nMaxSectionCount;
nIndex = i - 1;
}
nSum = Data[i];
nCount = 1;
nSection++;
}
}
//打印和验证结果
printf("nMaxSectionCount=%d ", nMaxSectionCount);
printf("nMaxSection=%d ", nMaxSection);
printf("nResult=%d ", nResult);
nSum = 0;
for (int i=nIndex-nMaxSectionCount+1; i<=nIndex; i++)
...{
printf("data[%d]=%d ", i, Data[i]);
nSum += Data[i];
}
printf("sum=%d, avg=%d ", nSum, nSum/nMaxSectionCount);
}
int main()
...{
ShowSection(Data, 20);
printf("=============================== ");
ShowSection1(Data, 20);
printf("=============================== ");
return 1;
}
分享到:
相关推荐
根据给定文件的信息,本文将深入探讨一种时间复杂度为O(n)的寻找中位数算法,并通过具体的源代码示例来分析其工作原理及实现细节。 ### 时间复杂度为O(n)的找中位数算法 #### 一、算法背景与目标 在计算机科学中...
在本篇【源代码】C++算法中,我们主要探讨的是如何在一维数组中去除重复元素,同时确保算法的时间复杂度为O(n),并且在整个处理过程中不额外开辟新的内存空间。这种问题在实际编程中非常常见,特别是在处理大量数据...
算法思想是,在要排序的一组数中,假设前面(n-1) 个数已经是排好顺序的,现在要把第 n 个数插到前面的有序数中,使得这 n 个数也是排好顺序的。如此反复循环,直到全部排好顺序。 冒泡排序是一种稳定的排序算法,...
在排序算法中,如快速排序、归并排序等使用了递归,它们在最好情况和平均情况下的时间复杂度为O(n log n),但在最坏情况下(如数据已经部分排序或完全排序)可能退化为O(n^2)。 了解这些排序算法的复杂度对于编写...
在计算机科学中,排序算法是数据处理的重要组成部分,它们用于将一组无序的数据按照特定的顺序排列。在Java编程语言中,实现各种排序算法能够帮助我们理解这些算法的工作原理,并评估其性能。以下是对选择排序、冒泡...
常见的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)、O(n^2)、O(2^n)等。 二、排序算法的稳定性 排序算法的稳定性是指在排序过程中,关键码相同的记录排序前后相对位置不发生改变。常见的稳定排序算法有插入排序...
计算时间复杂度主要关注算法中最基本的操作(如比较、赋值等),并忽略非基本操作和常数项的影响。具体步骤包括: - 确定基本操作:找出算法中重复执行次数最多的操作。 - 计算基本操作的执行次数:分析算法流程,...
在最坏的情况下,堆排序的时间复杂度为O(n log n),而在最好的情况下,如数组已经部分有序,时间复杂度仍为O(n log n)。由于堆排序不需要额外的存储空间,因此它的空间复杂度为O(1)。 2. **归并排序**: 归并排序...
- 另一个递推式`T(n) = T(n-1) + n`表示每个元素都需要进行一次操作,随着n的增加,时间复杂度是线性增长的,即`O(n^2)`。 3. **主定理(Master Theorem)**: - 主定理是分析递归算法时间复杂度的一种强大工具,...
- 最好情况:当输入数组已经是有序的,时间复杂度为 O(n),其中 n 为数组长度。 - 平均情况:时间复杂度为 O(n^2)。 - 最坏情况:当输入数组完全逆序时,时间复杂度同样为 O(n^2)。 **稳定性**:插入排序是一种稳定...
- 选择合适的数据结构可以极大地影响算法的复杂度,例如,二分查找的时间复杂度为O(log n),而线性查找为O(n)。 在这个作业中,你可能会被要求分析不同语言实现的算法,比较它们的复杂度,或者优化某个特定的算法...
这是因为插入排序在处理小数组或部分有序数组时,效率更高,其平均和最坏时间复杂度分别为O(n)和O(n^2)。对于快速排序而言,在数据接近有序时,递归调用的深度增加,性能下降。因此,将快速排序与插入排序结合使用,...
7. 快速排序:采用分治策略,通过一趟排序将待排记录分隔成独立的两部分,时间复杂度在平均情况下为O(n log n)。 8. 归并排序:递归地将数组分成两半,分别排序后再合并,时间复杂度始终为O(n log n)。 这些排序...
在计算机科学领域,排序算法是数据处理中至关重要的一部分,它涉及到如何有效地重新排列一组数据,使其按照特定标准(如升序或降序)排列。时间复杂度是衡量算法效率的重要指标,它描述了算法执行时间与输入数据规模...
在计算复杂度时,如果一个算法有多个部分,每个部分的空间需求分别是 S1(n) 和 S2(n),那么总的空间复杂度是这些部分复杂度的最大值,即 S(n) = O(S1(n) + S2(n)) = O(max(S1(n), S2(n)))。例如,如果一个算法同时...
希尔排序的时间复杂度取决于间隔序列的选择,通常为O(n^(3/2))至O(n log n)。希尔排序不是稳定的。 10. 桶排序(Bucket sort): 将元素分配到有限数量的桶里,然后分别对每个桶进行排序,最后合并所有桶中的结果...
在计算机科学中,排序算法是数据处理中至关重要的部分,它们用于将一组数据按照特定顺序排列。本节我们将深入探讨时间复杂度、简单排序算法以及评估算法效率的方法。 时间复杂度是衡量算法运行时间与输入数据量之间...
例如,O(n)表示线性时间复杂度,意味着算法执行时间与输入数据的大小成正比;而O(n²)则表示二次时间复杂度,意味着数据量加倍时,执行时间会呈四倍增长。理解并分析算法的时间复杂度有助于优化程序性能。 接着是**...
在计算机科学中,排序算法是数据结构领域的重要组成部分,它涉及到如何有效地重新排列一组数据,使其按照特定的顺序(如升序或降序)排列。排序算法的性能直接影响到程序的运行效率,尤其是在处理大量数据时。本篇将...
1. **分组与排序:** 将所有元素按照每 5 个一组进行分组,并对每个小组内的元素使用简单的排序算法(如冒泡排序)进行排序,以找到每组的中位数。 2. **选取基准值:** 对所有分组的中位数再次应用线性时间选择...