`
ah_fu
  • 浏览: 227991 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

复杂度为O(n)的取一组数中分布最密集的部分的算法

阅读更多
    公司有一个检测系统,在单位时间内将每次检测结果保存。由于检测的环境受到外界干扰,会随机地出现异常值。以前的办法是:取得所有检测结果的最大值作为最终值。由于异常值的出现,导致检测结果非常不准确。于是思考在整个检测结果曲线中,取分布最密集的部分作为结果。(如果异常值大大多于正常值,且异常值的出现范围相同,则这种方法也不可靠。好在正常值是大多数) 
    算法实现的原理为:将N个数排序,从第一个数开始累加,然后除以个数得到n个数以来平均值,把平均值和当前的数比较,如果范围超出一个阈值,则认为后面的数属于下一个段,然后重新从当前数开始累加比较。遍历完成后就可以把整段数据分成若干个段,段以内的数值的变化都是比较小的。
    在遍历中记录下每个段的长度,就可以得出数据最多的段,此段就是分布最密集的地方。把此段的值取平均就得到了检测中的正常值。
   算法的源码如下:
#include <stdio.h>
#include 
<string.h>

int Data[] = ...{2782023252632373844526769697281888892};
//段的阈值,决定数值变化的大小
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)的寻找中位数算法,并通过具体的源代码示例来分析其工作原理及实现细节。 ### 时间复杂度为O(n)的找中位数算法 #### 一、算法背景与目标 在计算机科学中...

    【源代码】C++算法(五)一维数组去重(复杂度为n且不新开辟空间)

    在本篇【源代码】C++算法中,我们主要探讨的是如何在一维数组中去除重复元素,同时确保算法的时间复杂度为O(n),并且在整个处理过程中不额外开辟新的内存空间。这种问题在实际编程中非常常见,特别是在处理大量数据...

    算法的时间复杂度和空间复杂度

    算法思想是,在要排序的一组数中,假设前面(n-1) 个数已经是排好顺序的,现在要把第 n 个数插到前面的有序数中,使得这 n 个数也是排好顺序的。如此反复循环,直到全部排好顺序。 冒泡排序是一种稳定的排序算法,...

    Java数组排序总结(冒泡_选择_插入_希尔)__递归算法的复杂度

    在排序算法中,如快速排序、归并排序等使用了递归,它们在最好情况和平均情况下的时间复杂度为O(n log n),但在最坏情况下(如数据已经部分排序或完全排序)可能退化为O(n^2)。 了解这些排序算法的复杂度对于编写...

    排序算法时间复杂度的分析java语言描述

    在计算机科学中,排序算法是数据处理的重要组成部分,它们用于将一组无序的数据按照特定的顺序排列。在Java编程语言中,实现各种排序算法能够帮助我们理解这些算法的工作原理,并评估其性能。以下是对选择排序、冒泡...

    NOIP普及组 提高组 CSP-J CSP-S初赛 算法的时间复杂度部分题目.pdf

    常见的时间复杂度有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. **归并排序**: 归并排序...

    NOIP普及组 提高组 CSP-J CSP-S初赛 算法的时间复杂度部分题目(2023.09.15)C.pdf

    - 另一个递推式`T(n) = T(n-1) + n`表示每个元素都需要进行一次操作,随着n的增加,时间复杂度是线性增长的,即`O(n^2)`。 3. **主定理(Master Theorem)**: - 主定理是分析递归算法时间复杂度的一种强大工具,...

    排序算法比较 时间复杂度 稳定性描述

    - 最好情况:当输入数组已经是有序的,时间复杂度为 O(n),其中 n 为数组长度。 - 平均情况:时间复杂度为 O(n^2)。 - 最坏情况:当输入数组完全逆序时,时间复杂度同样为 O(n^2)。 **稳定性**:插入排序是一种稳定...

    算法复杂度作业2

    - 选择合适的数据结构可以极大地影响算法的复杂度,例如,二分查找的时间复杂度为O(log n),而线性查找为O(n)。 在这个作业中,你可能会被要求分析不同语言实现的算法,比较它们的复杂度,或者优化某个特定的算法...

    快速排序的改进算法,时间复杂度的详细解答

    这是因为插入排序在处理小数组或部分有序数组时,效率更高,其平均和最坏时间复杂度分别为O(n)和O(n^2)。对于快速排序而言,在数据接近有序时,递归调用的深度增加,性能下降。因此,将快速排序与插入排序结合使用,...

    10.算法分析1_复杂度分析+查找+排序1

    7. 快速排序:采用分治策略,通过一趟排序将待排记录分隔成独立的两部分,时间复杂度在平均情况下为O(n log n)。 8. 归并排序:递归地将数组分成两半,分别排序后再合并,时间复杂度始终为O(n log n)。 这些排序...

    排序算法的时间复杂度分析

    在计算机科学领域,排序算法是数据处理中至关重要的一部分,它涉及到如何有效地重新排列一组数据,使其按照特定标准(如升序或降序)排列。时间复杂度是衡量算法效率的重要指标,它描述了算法执行时间与输入数据规模...

    1.2.3 算法的空间复杂度1

    在计算复杂度时,如果一个算法有多个部分,每个部分的空间需求分别是 S1(n) 和 S2(n),那么总的空间复杂度是这些部分复杂度的最大值,即 S(n) = O(S1(n) + S2(n)) = O(max(S1(n), S2(n)))。例如,如果一个算法同时...

    12种排序及时间复杂度稳定性

    希尔排序的时间复杂度取决于间隔序列的选择,通常为O(n^(3/2))至O(n log n)。希尔排序不是稳定的。 10. 桶排序(Bucket sort): 将元素分配到有限数量的桶里,然后分别对每个桶进行排序,最后合并所有桶中的结果...

    1.认识复杂度和简单排序算法1

    在计算机科学中,排序算法是数据处理中至关重要的部分,它们用于将一组数据按照特定顺序排列。本节我们将深入探讨时间复杂度、简单排序算法以及评估算法效率的方法。 时间复杂度是衡量算法运行时间与输入数据量之间...

    算法实验代码和报告(时间复杂度、0-1背包问题、分治与贪心、蛮力法)

    例如,O(n)表示线性时间复杂度,意味着算法执行时间与输入数据的大小成正比;而O(n²)则表示二次时间复杂度,意味着数据量加倍时,执行时间会呈四倍增长。理解并分析算法的时间复杂度有助于优化程序性能。 接着是**...

    排序算法介绍2.zip

    在计算机科学中,排序算法是数据结构领域的重要组成部分,它涉及到如何有效地重新排列一组数据,使其按照特定的顺序(如升序或降序)排列。排序算法的性能直接影响到程序的运行效率,尤其是在处理大量数据时。本篇将...

    线性时间选择中位数算法

    1. **分组与排序:** 将所有元素按照每 5 个一组进行分组,并对每个小组内的元素使用简单的排序算法(如冒泡排序)进行排序,以找到每组的中位数。 2. **选取基准值:** 对所有分组的中位数再次应用线性时间选择...

Global site tag (gtag.js) - Google Analytics