Java/C++实现快速傅里叶变换(FFT)

快速傅里叶变换不是一种新的变换,而是傅里叶变换的一种快速算法,这个算法可以将普通的离散傅里叶变换(DFT)的时间复杂度O(n*n)降到O(n
log n),大大提高了傅里叶变换的速度。快速傅里叶变换算法的提出,使傅里叶变换在通信领域得到了极大地运用和发展。
在ACM中,快速傅里叶变换通常用于大数的乘法。当两个数大到连JAVA的BI都无法承受时,就该使用快速傅里叶算法了。该算法是将两个数,都写成多项式矩阵,然后对其进行离散傅里叶变换。通信领域有句很经典的话,叫做时域卷积,频域相乘。所以将两个数的多项式系数矩阵进行离散傅里叶变换后,就可以对其进行直接相乘了。将相乘后得结果再进行傅里叶逆变换(DTFT)。

我之前怎么也无法理解快速傅里叶算法,因为当时觉得太复杂了太难了,看都看不进去。但是,由于专业课,所以无可避免地会在各个课上与傅里叶变换碰面。就在上一周,我们的数字信号处理老师,花了好几节课的时间,给我们讲解了快速傅里叶算法,我当时听得很认真,并自认为听懂了。但是,当我想用自己脑子里的快速傅里叶算法求解大数相乘的题目时,却发现无从下手。我根本就不知道怎么去运用它。当时我就在想,这个算法我必须掌握它,不仅仅是因为它会出现在ACM中,更是因为它在我的专业上也占据了极其重要的地位。于是乎,我花了两天的时间,查资料,终于搞懂了这个强大的算法。我也发现有些大神写的关于FFT的文章确实非常不错,清晰易懂,我自己也收藏了,推荐给大家,大家一起学习。

超级易懂的傅里叶变换


快速傅里叶变换(FFT)


JAVA代码
import java.util.Arrays;
import java.util.Scanner;
import java.util.Vector;

/**
 * Created by jal on 2017/12/6 0006.
 */
public class DIT_FFT {
   
    private static int maxn;
    public static void main(String[] args) {
   
        Scanner scanner = new Scanner(System.in);
        String numstr1 = scanner.next();
        String numstr2 = scanner.next();
        int len =numstr1.length()+numstr2.length();
        maxn = 0;
        double temp = log2(len);
        double floortemp = Math.floor(temp);
        if(floortemp == temp){
   
            maxn = len;
        }else {
   
            maxn = (int)Math.pow(2,floortemp+1);
        }
        Complex []arra = createArray(maxn);
        Complex []arrb =createArray(maxn);
        Complex []arrc =createArray(maxn);
        Complex []arrA = createArray(maxn);
        Complex []arrB = createArray(maxn);
        Complex []arrC = createArray(maxn);

        char []a = numstr1.toCharArray();
        int j = 0;
        for(int i = a.length - 1; i >= 0; i--){
   
            arra[j++] = new Complex(a[i] - '0');
        }
        j = 0;
        char []b = numstr2.toCharArray();
        for(int i = b.length - 1; i >= 0; i--){
   
            arrb[j++] = new Complex(b[i] - '0');
        }
        //System.out.println(Arrays.toString(arra));

        //invert(arra);



        arrA = fft(arra);
        System.out.println(Arrays.toString(arrA));
        //invert(arrb);

        arrB = fft(arrb);
        //System.out.println(Arrays.toString(arrB));
        for(int i = 0; i < arrC.length; i++){
   
            arrC[i] = arrA[i].times(arrB[i]);
        }
        //System.out.println(Arrays.toString(arrC));
        arrc = ifft(arrC);
        Vector<Integer> vector = new Vector<>();
        vector = toIntOfString(arrc);
        String str = "";
        char vectorCHar[] = new char[vector.size()];
        for(int i = 0; i < vectorCHar.length; i++){
   
            vectorCHar[i] = (char)(vector.get(i) + '0');
        }
        str =String.valueOf(vectorCHar);
        str = new StringBuffer(str).reverse().toString();
        //System.out.println("str:"+str);
        str = trim(str);
        System.out.println(str);

    }
    private static String trim(String value) {
   

        int len = value.length();
        int st = 0;
        char[] val = value.toCharArray();    /* avoid getfield opcode */

        while (
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值