利用c语言实现大数据处理_c语言实现at指令返回数据处理 - CSDN
精华内容
参与话题
  • 所以这里要讨论的是对于N非常的情况,即假设由于存储空间有限,我们不能存储整个窗口的数据。 根据滑动窗口共有2N种表示简单推算,任何能给出确切结果的算法都需要O(N)的空间,即该问题必须寻找近似算法。Datar-...

    对于该查询,若空间足够,可以通过空间复杂度O(N),时间复杂度O(1)的简单的加减得到查询结果。所以这里要讨论的是对于N非常大的情况,即假设由于存储空间有限,我们不能存储整个窗口的数据。

    根据滑动窗口共有2N种表示简单推算,任何能给出确切结果的算法都需要O(N)的空间,即该问题必须寻找近似算法。Datar-Gionis-Indyk-Motwani Algorithm(DGIM算法)是其中一种:该算法仅使用O(log2N)的空间,时间复杂度为O(logN)。     首先假设对于二进制流,其中每个位可以用一个时间戳(timestamp)标志该位进入流的时间(对于大小为N的滑动窗口,该时间戳可以用O(logN)位表示)。
    
    
    
     DGIM算法利用桶(bucket)对滑动窗口进行划分,每个桶保存以下信息:
    

    桶的最右边位即最后进入流的位的时间戳;
    桶的大小,即桶中1的个数,该数目位2的幂。
    对于以上信息,保存时间戳需要logN的空间,保存桶的大小需要loglogN的空间。

    使用桶对滑动窗口进行划分时遵循以下5条规则:
    

    桶最右边的位必须是1;
    1个位最多属于1个桶;
    每种大小的桶有1个或者两个(从1到最大的桶的大小);
    每个桶的大小是2的幂;
    桶的大小从右到左非降序排列;
    举例:
    这里写图片描述

    DGIM算法中数据结构的更新:
    

    每一个新的位进入滑动窗口后,最左边一个位从窗口中移出(同时从桶中移出);如果最左边的桶的时间戳是当前时间戳减去N(也就是说桶里已经没有处于窗口中的位),则放弃这个桶;
    对于新加入的位,如果其为0,则无操作;否则建立一个包含新加入位的大小为1的桶;
    由于新增一个大小为1的桶而出现3个桶大小为1,则合并最左边的两个桶为一个大小为2的桶;合并之后可能出现3个大小为2的桶,则合并最左边两个大小为2的桶得到一个大小为4的桶……依次类推直到到达最左边的桶。
    举例(上图中最右边进入一个新的1后的结果):
    这里写图片描述

    可以给出DGIM的存储开销:桶的个数O(logN),每个桶可以用O(logN)空间表示,保存表示一个窗口的所有桶所占的空间为O(log2N)。

    对于查询,首先寻找含最近k个位的拥有最大时间戳的桶b,查询结果为在k个为中所有桶的大小,加上b的大小的一半。一次查询的时间复杂度为O(logN)。
    
    该估计值误差(fractional error)的上下限为:
    

    至少是正确值的50%:最差情况b中都是1,估计误差值是b的一半。
    最多超过正确值的50%:最差情况b只有最右边一位为1。

    下面是c语言实现代码

    #include "stdio.h"
    #include "stdlib.h"
    
    typedef struct
    {
        int size;
        int time_stamp;
    }BucketNode,*Bucket;
    
    int count_bucket = 0;
    
    void merge(Bucket buc,int n);
    void estimate(Bucket buc,int count_window,int n);
    void accurate(int *slip_window,int count_window);
    
    int main()
    {
        int data;    //接收数据流
        int n = 1;    //时间戳
        int t;    //需要输入的任意时刻
        int i;
    
        Bucket buc  = (Bucket)malloc(50 * sizeof(BucketNode));    //桶_结构体指针数组
    
        int count_window;    //滑动窗口大小
        int *slip_window;    //滑动窗口数组
        FILE *fp;
    
        printf("请输入滑动窗口大小:\n");
        scanf("%d",&count_window);    //输入滑动窗口大小
        slip_window = (int *)malloc(count_window * sizeof(int));    //滑动窗口数组分配空间
    
        printf("请输入时刻:\n");
        scanf("%d",&t);
    
        fp = fopen("01stream.txt","r");    //打开文件
        while(1)
        {
            fscanf(fp,"%d",&data);    //读取一个数据
            if(feof(fp))
            {
                break;
            }
    
            *(slip_window + (n+1)% count_window) = data;    //把data数据放到滑动窗口数组中
    
            if(data == 1)    //如果读到的是1 创建新桶
            {
                buc[count_bucket].size = 1;
                buc[count_bucket].time_stamp = n;
    
                if(count_bucket > 1) 桶总数目大于2的时候才有可能合并
                {
                    merge(buc,count_bucket);    //合并    
                }
                count_bucket++;   //创建新桶,所以桶数目加1
    
            }
            n++;    //时间戳加1
            if(n == t + 1)
            {
                break;
            }
        }
        printf("字符流个数:%d\n",n - 1);
        printf("桶数目:%d\n",count_bucket);    //桶总数
        fclose(fp);
    
        for (i = 0; i < count_bucket; i++)
        {
            printf("第%2d桶  桶大小:%5d   时间戳:%d\n",i,buc[i].size,buc[i].time_stamp);
        }
    
        estimate(buc,count_window,n-1);
        accurate(slip_window,count_window);
    
    }
    
    //合并
    void merge(Bucket buc,int n)
    {
        int i,j;
        for(i = n; i > 1; i--)
        {
            if( (buc[i].size == buc[i-1].size) && (buc[i-1].size == buc[i-2].size) )
            {
                buc[i - 2].size *= 2;
                buc[i - 2].time_stamp = buc[i - 1].time_stamp;
                buc[i - 1]= buc[i];
                for(j = i;j < count_bucket; j++)
                {
                    buc[j] = buc[j+1];
                }
                count_bucket--;
            }
        }
    }
    
    //估算
    void estimate(Bucket buc,int count_window,int n)
    {
        int i;
        int sum = 0;
        for(i = count_bucket; i > 0; i--)
        {
            if(buc[i].time_stamp > n - count_window)
            {
                sum += buc[i].size;
            }
            else
            {
                sum -= (buc[i+1].size)/2;
                break;
            }
        }
    
        printf("估算滑动窗口内1_bit个数:%d\n",sum);
    }
    
    
    //精确计算窗口1个数
    void accurate(int *slip_window,int count_window)
    {
        int n = 0,i;
        for(i = 0; i < count_window; i++)
        {
            if(*(slip_window + i) == 1)
            {
                n++;
            }
        }
        printf("滑动窗口内1_bit精确个数为:%d\n",n);
    
    }

    运行:
    这里写图片描述

    展开全文
  • 循环队列–C语言实现数据结构

    万次阅读 多人点赞 2017-06-22 19:07:59
    循环队列–C语言实现–数据结构目录循环队列C语言实现数据结构目录 一 要求 二 循环队列 三 循环队列的算法设计 1 建立循环队列 2 置空队列 3 入队 4 出队 5 打印队 四 程序 1 程序的结构 2 程序源码 五 程序测试 1 ...

    循环队列–C语言实现–数据结构


    目录


    (一) 要求

    假设以数组sequ[m]存放循环队列的元素,同时设变量rear和quelen 分别指示循环队列中队尾元素的位置和内含元素的个数。编写实现该循环队列的入队和出队操作的算法。提示:队空的条件:sq->quelen==0;队满的条件:sq->quelen==m。


    (二) 循环队列

    定义:为充分利用向量空间,克服”假溢出”现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现, 当然也可以利用顺序表来实现。顺序表就是我们熟悉的数组 eg. sun[]
    回顾:我们再来回顾一下关于顺序队列的重要知识点。队列通常与栈对应,栈是一种后进先出的单端(尾端)处理的数据结构;那么与之对应的队列是一种先进先出的双端(头尾两端)的数据结构。队列的特点就是在一段进行入队(存储数据)操作,在另一端进行出队(删除数据)操作。
    为什么设计循环队列:大家在处理队列的时候,会遇到如下情况。例如说:我们的队列空间能够容纳1000个元素。首先,格格入队1000个元素,队列上溢,此时为“真溢出”。那么现在我们进行出队操作,我们一直出队,一直出队, 知道1000个元素全部被删除,此时我们发现队列仍然处于“上溢”状态,why? 其实原因很简单,在非循环队列当中,无论我们的front指(偏移)到哪里,只要我们的rear指(偏移)向上阙,那么队列就是“满溢”的。这就造成了空间明明还被占据着,但是队列却已经无用武之地的窘境。对于空间有限的计算机来说,这无疑是一种浪费。也不是一个优秀的程序猿想要看到的。所以在这种情况下,循环队列诞生了。循环队列当中的“满溢”只有一种情况,那就是所有数据空降都被占领了。而不会存在非循环队列当中的“假溢出”现象。


    我们所常见的顺序循环队列通常有两种数据结构。

    结构一

    typedef struct
    {
        datatype sequ[m];
        //sequ[]为我们所建立的顺序表(sequence)
        int  front,rear;
        //front表示队列头的偏移量,rear表示队列的尾的偏移量
    }qu;//qu是队列(queue)的缩写

    这里写图片描述

    结构二

    typedef struct
    {
        datatype sequ[m];
        //sequ[]为我们所建立的顺序表(sequence)
        int  rear, quelen;
        //rear表示队列的尾的偏移量,quelen表示的是队列中元素的个数
    }qu;//qu是队列(queue)的缩写

    那通过观察这两种机构我们能够很容易的发现,数据结构并不是固定的。我们觉得那种算法比较更合理,我们觉得哪种数据结构方便我们设计算法,那么我们就建立哪种数据结构。在本文当中,我们采用第二种数据结构。显而易见的是,当我们采用第二种数据结构时,我们建立的一个队列指针(qu*sq)队空的条件:sq->quelen==0;队满的条件:sq->quelen==m。


    (三) 循环队列的算法设计


    在上面我们了解了循环队列的数据机构,但是仅仅学会了数据结构还远远不够。我们设计数据结构的目的是为了更好的存储数据,并利用数据。下面我们来看一看关于循环队列我们要掌握哪些最基本的算法(利用数据机构)。


    3.1 建立循环队列

    //建立队
    qu* creatqueue();//函数声明
    qu* creatqueue()//函数实现
    {
        qu *sq;
        sq=(qu*)malloc(sizeof(qu));
        return sq;  
    }

    3.2 置空队列

    //置空队
    void setnull(qu*);//函数声明
    void setnull(qu *sq)//函数实现
    {
        sq->rear = m - 1;
        sq->quelen = 0;
    }

    3.3 入队

    //入队
    void enqueue(qu*, datatype);//函数声明
    void enqueue(qu*sq, datatype x)//函数实现
    {
        if (sq->quelen == 5)
            printf("Errot! The queue will be overflow! \n");
        else if((sq->rear+1)==m)
        {
            sq->rear = (sq->rear + 1) % m;
            sq->sequ[sq->rear] = x;
            sq->quelen++;
            printf("过5入队成功!\n");
        }
        else
        {
            sq->rear++;
            sq->sequ[sq->rear] = x;
            sq->quelen++;
            printf("入队成功!\n");
        }
    }

    **算法流程图**


    3.4 出队

    //出队
    datatype *dequeue(qu*);//函数声明
    datatype *dequeue(qu*sq)//函数实现
    {
        datatype sun=0;
        if (sq->quelen == 0)
        {
            printf("Error! The queue will be under flow!\n");
            return 0;
        }
        else if ((sq->rear + 1) >= sq->quelen)
        {
            sq->quelen--;
            sun = sq->sequ[sq->rear - sq->quelen];
            return(&sun);
        }
        else    //  if(sq->rear < sq->quelen)
        {
            sq->quelen--;
            sun = sq->sequ[sq->rear - sq->quelen + m];
            return(&sun);
        }
    }
    

    **算法流程图**


    3.5 打印队

    //打印队
    void print(qu*);//函数声明
    void print(qu*sq)//函数定义
    {
        if (sq->quelen == 0)
            printf("Error! The queue is Null!\n");
        else if ((sq->rear + 1) >= sq->quelen)
        {
            int i = sq->rear + 1 - sq->quelen;
            for (i; i <= sq->rear; i++)
                printf("%d   ", sq->sequ[i]);
        }
        else
        {
            int t = sq->rear - sq->quelen + m +1;
            int time = 1;
            for (t; time <= (sq->quelen); time++)
            {
                printf("%d   ", sq->sequ[t]);
                t++;
                if (t == m)
                {
                    t = 0;
                    continue;
                }
                else
                {
                    continue;
                }
            }
        }
        printf("\n");
    }

    (四) 程序


    下面我们来设计一个程序测试我们的数据机构与算法


    4.1 程序的结构

    **程序结构**


    4.2 程序源码

    注意:该程序由Microsoft Visual Studio Enterprise 2015编译器进行调试。受制于编译器品牌及版本不同等不可抗因素造成的编译失败,请自行调整。

    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    #define m 5
    
    //循环队列的结构类型定义
    typedef int datatype;
    typedef struct
    {
        datatype sequ[m];
        int  rear, quelen;
    }qu;
    
    //函数声明
    qu* creatqueue();
    void setnull(qu*);
    void enqueue(qu*, datatype);
    datatype *dequeue(qu*);
    void print(qu*);
    
    //主函数
    void main()
    {
        qu *sq= creatqueue();
    
        datatype x, *p;
        int key;
    
        setnull(sq);
        do
        {
            printf("1.Enter Queue   2.Delete Queue   3.clc display   4.print queue   -1.Quit:");
            scanf_s("%d", &key);
            switch (key)
            {
            case 1:  printf("Enter the Data:"); scanf_s("%d", &x);
                enqueue(sq, x);  break;
            case 2:  p = dequeue(sq);
                if (p != NULL) printf("%d\n", *p);
                break;
            case 3:system("cls"); break;
            case 4:print(sq); break;
            case -1: exit(0);
            }
        } while (1);
    }
    
    //建立队
    qu* creatqueue()
    {
        qu *sq;
        sq=(qu*)malloc(sizeof(qu));
        return sq;  
    }
    //置空队
    void setnull(qu *sq)
    {
        sq->rear = m - 1;
        sq->quelen = 0;
    }
    
    //入队
    void enqueue(qu*sq, datatype x)
    {
        if (sq->quelen == 5)
            printf("Errot! The queue will be overflow! \n");
        else if((sq->rear+1)==m)
        {
            sq->rear = (sq->rear + 1) % m;
            sq->sequ[sq->rear] = x;
            sq->quelen++;
            printf("过5入队成功!\n");
        }
        else
        {
            sq->rear++;
            sq->sequ[sq->rear] = x;
            sq->quelen++;
            printf("入队成功!\n");
        }
    }
    
    
    //出队
    datatype *dequeue(qu*sq)
    {
        datatype sun=0;
        if (sq->quelen == 0)
        {
            printf("Error! The queue will be under flow!\n");
            return 0;
        }
        else if ((sq->rear + 1) >= sq->quelen)
        {
            sq->quelen--;
            sun = sq->sequ[sq->rear - sq->quelen];
            return(&sun);
        }
        else    //  if(sq->rear < sq->quelen)
        {
            sq->quelen--;
            sun = sq->sequ[sq->rear - sq->quelen + m];
            return(&sun);
        }
    }
    
    //打印队列
    void print(qu*sq)
    {
        if (sq->quelen == 0)
            printf("Error! The queue is Null!\n");
        else if ((sq->rear + 1) >= sq->quelen)
        {
            int i = sq->rear + 1 - sq->quelen;
            for (i; i <= sq->rear; i++)
                printf("%d   ", sq->sequ[i]);
        }
        else
        {
            int t = sq->rear - sq->quelen + m +1;
            int time = 1;
            for (t; time <= (sq->quelen); time++)
            {
                printf("%d   ", sq->sequ[t]);
                t++;
                if (t == m)
                {
                    t = 0;
                    continue;
                }
                else
                {
                    continue;
                }
            }
        }
        printf("\n");
    }
    
    

    (五) 程序测试


    5.1 入队列

    **入队列及上溢检测**


    5.2 出队列

    出队列及下溢检测


    5.3 打印队列

    前面已经用到了打印队列,所以格格不再赘述,大家由5.2&5.3可知打印队列是成功的。


    (六) 源程序及封装软件下载

    下载地址


    格格是一枚智能专业的本科在校生,很愿意和各位大佬交流。如果大家有愿意交朋友的,可以加格格的QQ:446019725,声明是CSDN即可。



    展开全文
  • 这里我利用的是fopen()函数进行操作的,个人认为运用比较简单。 fopen函数是打开一个文件,其调用的一般形式为: 文件指针名=fopen(文件名,使用文件方式); 文件名一般都是路径加上文件名 文件使用方式由r,w,a,t,b...

    这里我利用的是fopen()函数进行操作的,个人认为运用比较简单。
    fopen函数是打开一个文件,其调用的一般形式为:
    文件指针名=fopen(文件名,使用文件方式);
    文件名一般都是路径加上文件名

    文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:
    r(read): 只读
    w(write): 只写
    a(append): 追加
    t(text): 文本文件,可省略不写
    b(binary): 二进制文件
    +: 读和写
    2) 凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。
    3) 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。
    4) 若要向一个已存在的文件追加新的信息,用“a”方式打开文件。如果指定文件不存在则尝试创建该文件。
    5) 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。

    #include<stdio.h>	
    int sum; 
    char a[10];
    void read_file()//读文件的数据 
    {
    	FILE *fp;
    	fp=fopen("data.txt","r");	//第一个 "" 里面是文件路径和文件名,第二个 "" 是执行相应的权限操作 
    	fscanf(fp,"%s %d",&a,&sum);	//这一条语句和 feof函数的特点有关,当指针的 fp走到文件末尾时返回值任然是非空,会导致最后一行数据多输出
    	//对上面有兴趣的,可以换成我注释了的函数,就在下面 
    	while(!feof(fp))	//当文件为空时结束 
    	{	 
    		printf("%s %d\n",a,sum);//将文件的数据赋值给 a 和 sum 变量,然后在进行输出 
    		fscanf(fp,"%s %d",&a,&sum);
    	}
    	fclose(fp);//关闭文件 
    }
    
    void write_file()//将数据追加写入文件中 
    {
    	FILE *FP;
    	FP=fopen("data.txt","a") ;	//在原有的文件上追加数据 
    	scanf("%s %d",&a,&sum);		//输入数据 
    	fprintf(FP,"%s %d\n",a,sum); //将数据存入文件中 
    	fclose(FP);
    }
    int main()
    {
    	int n;
    	while(~scanf("%d",&n))
    	{
    		if(n==1)	//读文件数据 
    			read_file();
    		else if(n==2) 	// 将数据写入文件 
    			write_file();
    	}
     } 
     
     //void read_file()//读文件的数据 
    //{
    //	FILE *fp;
    //	fp=fopen("data.txt","r");
    //	while(!feof(fp))
    //	{	 
    //		fscanf(fp,"%s %d",&a,&sum);
    //		printf("%s %d\n",a,sum);
    //	}
    //	fclose(fp);
    //}
    

    在这里插入图片描述在这里插入图片描述
    总结:文件的读写的方法还有很多,希望文章对你们有所帮助,如有不足或疑惑欢迎评论区怕评论。

    展开全文
  • 利用C语言实现FFT、IFFT运算

    千次阅读 2019-11-01 12:19:47
    一、FFT、IFFT算法实现 上述分别为FFT、IFFT公式。下面首先讨论FFT的算法实现。本文采用输入逆序、输出顺序的FFT计算方法。**实质上就是在时域对x(n)进行“奇偶分类”、在频域上对X(k)进行“前后分类”。**值得...

    一、FFT算法理论

    FFT、IFFT
    上述分别为FFT、IFFT公式。下面首先讨论FFT的算法实现。
    本文采用输入逆序、输出顺序的FFT计算方法。实质上就是在时域对x(n)进行“奇偶分类”、在频域上对X(k)进行“前后分类”。 值得说明的是,这里的“奇”和“偶”是相对的概念,并不完全是通常我们所理解的“奇”和“偶”。下面将给出一个例子进行说明:
    FFT运算示例
    ·图中,总共可以分为 “三级” ,每一级包含若干 “蝶形计算单元”。每一个蝶形单元的结构如下:蝶形运算单元
    因此,进行FFT运算只需考虑三件事情。一、将输入序列倒序排列,也就是进行奇偶分类。二、实现最基本的蝶形计算单元。三、根据规律,划分出FFT运算的级数,并且确定出每一级中参与蝶形运算的数据分组。

    二、FFT运算的代码实现

    1. 输入倒序排列(奇偶分类)。事实上,将输入倒序排列就是进行了奇偶分类。如果FFT的点数为8,那么这8个数的二进制表示分别为000,001,010,011,100,101,110,111。进行二进制层面倒序排列就变为000,100,010,110,001,101,011,111;重新转变为十进制就是0,4,2,6,1,5,3,7。 上面的计算方式对人类来说是很方便的,但是对于电脑来说,效果并不是太好,因此需要另外发现一种规律。
    2. 输入奇偶分类(倒序排列)。上面已经提到,倒序排列实际上就是在进行奇偶分类,而进行奇偶分类对电脑来说会简单很多。总结1中提到的规律,三位二进制数可以理解为FFT运算的级数。我们可以发现,在倒序排列完成后,“偶数”总是排在“奇数”前面。 这里需要提出“偶中的偶”,“奇中的奇”的概念。即每次进行“余2”运算,结果是0的都排在前面。现在看来,电脑实现算法的方式就是每次进行“余2”运算,进行奇偶分类;然后进行“除2”运算,再进行“余2”运算,进行奇偶分类……直到最后排序完成。 实现代码如下:
    void reverse()		//输入倒序
    { 
    	complex temp;
    	char* flag = (char*)malloc(N * sizeof(char));	//用于标记是否被换过,若为1,则已经换过
    	int i, j, current_n, target_n;
    	for (i = 0;i < N;i++) {
    		flag[i] = 0;
    	}
    	for (i = 0;i < N;i++) {
    		current_n = i;
    		target_n = 0;
    		//获取两个互为倒序的标号,换种思路
    		for (j = 0;j < bits;j++) {
    			target_n = target_n + (int)((current_n % 2) * pow(2, bits - j - 1));
    			current_n /= 2;
    		}
    		current_n = i;
    		//对应标号值互换
    		if (current_n != target_n && flag[current_n] != 1) {
    			temp = x[current_n];
    			x[current_n] = x[target_n];
    			x[target_n] = temp;
    			flag[target_n] = 1;
    		}
    	}
    	free(flag);
    }
    

    说明:complex为自己定义的复数数据结构。再次强调,奇偶分类就是倒序排序。二者是一样的。

    1. 蝶形运算单元的实现。分析蝶形运算单元,两输入、两输出,因此蝶形运算单元需要注意的就是输入、输出采用同一片内存存储即可,也就是让输出数据覆盖输入数据,这样可以有效节约存储资源。
    void butterfly(int x1_point, int x2_point, complex wn)	//蝶形计算单元
    {
    	complex result1, result2, T;
    	T = multiplication(x[x2_point], wn);
    	result1 = add(x[x1_point], T);
    	result2 = sub(x[x1_point], T);
    
    	x[x1_point] = result1;
    	x[x2_point] = result2;
    }
    
    

    说明:上面multiplication、add、sub方法均为自己定义,wn为旋转因子。

    1. 进行单级FFT运算。需要注意的就是总结规律。总结出两对偶结点的“结点跨距”、“分组间隔”、“分组数”……有了这些才能够编写将参与蝶形运算的数据分类配对。
    void single_fft(int m)			//进行单级的fft运算
    {
    	//首先进行分组
    	int point_distance = (int)pow(2, m - 1);	//结点跨距
    	int group_distance = 2 * point_distance;	//分组间隔
    	int group_count = N / group_distance;		//分组数
    
    	int group_header = 0;
    
    	int x1, x2;								//参与计算两结点的标号
    	complex w;
    
    	int i, j;								//循环控制符
    	//分组
    	for (i = 0;i < group_count;i++) {
    		//获取一组的标号范围
    		group_header = i * group_distance;
    		//将每组分成两半,前一半均为x1,后一半均为x2
    		for (j = 0;j < group_distance / 2;j++) {
    			w = w_builder(m, j);
    			x1 = j + group_header;
    			x2 = x1 + point_distance;
    			butterfly(x1, x2, w);
    		}
    	}
    }
    
    1. 有了单级FFT运算以后,将每一级组合就可以实现FFT运算了。
    complex* fft(int fft_point, int xn_length, complex* xn)		//fft最终封装
    {
    	int i;
    	//初始化
    	fft_init(fft_point, xn_length, xn);
    	//输入倒序
    	reverse();
    	//fft运算
    	for (i = 1;i <= bits;i++) {
    		single_fft(i);
    	}
    	return x;
    }
    

    三、IFFT算法理论

    IFFT算法理论
    从上面的等式可以看出,括号里面的内容实际上就是FFT运算。也就是说只需要对输入、输出序列进行一定的处理,就可以利用刚刚已经做好的FFT算法实现IFFT的运算!

    四、IFFT运算的代码实现

    complex* ifft(int xk_length, complex* xk)		//ifft最终封装
    {
    	int i;
    	//对输入序列进行处理
    	ifft_init(xk_length, xk);
    	//套用fft算法
    	reverse();
    	for (i = 1;i <= bits;i++) {
    		single_fft(i);
    	}
    	//对输出序列进行处理
    	for (i = 0;i < N;i++) {
    		x[i] = conjugate(x[i]);		//求共轭
    		x[i].real /= N;
    		x[i].imaginary /= N;
    	}
    	return x;
    }
    

    五、总结

    本文也程序也考虑到了FFT自动补零问题的处理,大家可以参考完整代码(FFT、IFFT均验证正确)。FFT.zip

    展开全文
  • C语言是一种结构化的编程语言,以模块化功能和处理过程设计为主,从而实现数据与代码分隔。面向对象的编程语言,核心是类,类用来创造对象的模板,类的三要素为:封装,继承,多态。C语言本身对面向对象的支持很弱,...
  • c语言实现二叉排序树的插入、查找、删除、打印树

    万次阅读 多人点赞 2019-02-23 15:08:13
    c语言实现二叉树的插入、查找、删除、打印树
  • C语言实现神经网络中的卷积

    千次阅读 2019-04-15 19:54:02
    卷积神经网络 ...这篇博客主要用C语言实现传统的卷积,就是基于滑动窗口的卷积。 #include<stdio.h> #define M 18 //图像尺寸 18 *18 * 3 #define N 3 //卷积核尺寸 3 * 3 * 3 #define K...
  • 数据压缩解析及C语言实现介绍

    千次阅读 2013-07-10 23:26:12
    引言  现有的压缩算法有很多种,但是都存在一定的局限性,比如:LZw[1]。主要是针对数据量较的图像之类的进行压缩,不适合对...本文假设该批数据为纯数字数据实现压缩并解压缩算法。  1 数据压缩概念  数
  • C语言实现一个C语言的编译器

    万次阅读 多人点赞 2020-06-12 10:25:28
    C语言实现一个C语言的编译器 目标:基于C0+文法的编译器,生成语法树,四元式,符号表,最后生成X86汇编(386) 接下来介绍一下整个的设计和实现思路(C0+ 文法是指 以C0为基础,另外增加了一些C0没有的文法 )...
  • C语言实现HashMap

    万次阅读 2019-04-28 14:53:10
    C语言实现HashMap在做算法题时,需要使用到HashMap提高效率,虽然高级语言中大豆实现了这种数据结构,但是高级语言的效率低,于是打算自己实现HashMap,加深理解,使用C语言实现了HashMap的创建(CreateHashMap)、取...
  • 利用C语言实现二维码显示

    千次阅读 2018-03-08 14:02:52
    11/03/2017在上一个作者的基础上添加自己的理解和处理的问题1.代码文件中有很多.c .h 文件,本程序只用到了QR_Encode.c 和 QR_Encode.h 其他文件如果不用,可以删除2.其他文件的代码也是用来生成二维码的,直接调用&...
  • C语言实现大小端判断

    千次阅读 2016-01-21 09:25:35
    大端小端的概念(以下概念来自网络) 端模式(Endian)的这个词出自Jonathan Swift书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类,从圆头开始将鸡蛋敲开的人被归为Big Endian,从...
  • 【Linux】C语言实现文件夹拷贝

    万次阅读 多人点赞 2015-12-25 15:19:25
    在《【Linux】利用C语言文件流复制单一文件》(点击打开链接)讲述了如何用C语言拷贝文件,但是这只能拷贝单一文件。如果你要用LinuxC拷贝整个文件夹,同样要像《【Java】利用文件输入输出流完成把一个文件夹内的...
  • C语言实现一个学生成绩管理系统 题目: 学生成绩管理系统 功能: 实现学生信息管理。包括:录入、查询、排序等功能。 要求: 用数据文件保存学生基本信息(学号 姓名 课程1 课程2 课程3…) ,利用菜单可以循环实现...
  • 银行家算法 C语言实现

    千次阅读 2019-05-05 22:46:18
    C语言实现银行家算法 这几天老师要求使用C语言实现银行家算法,数据可以自定义。想来想去还是照着书现成的数据来模拟一下。 教材使用的是西安电子科大出版社的《计算机操作系统》汤小丹 第四版。模拟数据使用的是P...
  • // 数据类型说明: // WORD:16位无符号短整形,占2个字节 // DWORD:32位无符号短整形,占4个字节 // LONG:有符号32位整形,占4个字节 // RGBQUAD:用于定义调色板数组元素的类型 // LPBITMAPINFOHEADER:位图信息...
  • C语言实现封装、继承和多态

    千次阅读 2016-03-19 11:06:08
    C语言实现封装、继承和多态–通过创建一个VTable(virtual table)和在基类和派生类对象之间提供正确的访问 如何实现 C 语言的继承和多态–通过函数指针来实现的继承与多态,简单明了,animal基类,cat,dog两个...
  • 使用C语言实现CRC校验的方法

    万次阅读 2015-04-28 23:16:30
    本篇文章是对使用C语言实现CRC校验的方法进行了详细的分析介绍,需要的朋友参考下 CRC(Cyclic Redundancy Check)校验应用较为广泛,以前为了处理简单,在程序中大多数采用LRC(Longitudinal Redundancy Check)校验...
  • C语言实现简单的内存管理机制

    千次阅读 2020-02-15 14:17:55
    在C类型程序中,栈内存比较珍贵,部分用在局部或者类成员(因为稀少… 不适合长时间占用一块栈内存),对于大量数据一般使用堆来分配。重复用堆分配有一个显著的缺点就是容易造成外部碎片,在这种情况下系统内存不再...
  • RSA算法详解及C语言实现

    千次阅读 2016-11-07 16:34:31
    RSA算法详解及C语言实现
1 2 3 4 5 ... 20
收藏数 85,785
精华内容 34,314
关键字:

利用c语言实现大数据处理