leecode,rt_phm更新更新

This commit is contained in:
markilue 2023-05-25 11:54:29 +08:00
parent 00f5d9ebd1
commit 67bcb4b0bc
22 changed files with 14013 additions and 36 deletions

View File

@ -0,0 +1,12 @@
package com.markilue.leecode.hot100.interviewHot.singlestack;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.interviewHot.singlestack
*@Author: markilue
*@CreateTime: 2023-05-25 11:29
*@Description: TODO 力扣239 滑动窗口最大值
*@Version: 1.0
*/
public class LC_239_MaxSlidingWindow {
}

View File

@ -13,7 +13,7 @@ import java.util.LinkedList;
*@Description: TODO 力扣503 下一个更大元素II
*@Version: 1.0
*/
public class T503_NextGreaterElements {
public class LC_503_NextGreaterElements {
@Test
public void test() {

View File

@ -0,0 +1,43 @@
package com.markilue.leecode.hot100.interviewHot.speical;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-25 10:39
*@Description: TODO 力扣238 除自身以外数组的乘积
*@Version: 1.0
*/
public class T71_238_ProductExceptSelf {
@Test
public void test() {
int[] nums = {1, 2, 3, 4};
System.out.println(Arrays.toString(productExceptSelf(nums)));
}
//思路:考虑分别使用一个left和right记录这个数左边数的乘积和右边数的乘积最后计算总和
//其实本题的矛盾点就在于:如果不想要当前就会损失前面的或者后面的就会瞻前顾后遍历两次即可
public int[] productExceptSelf(int[] nums) {
int[] left = new int[nums.length];
int[] right = new int[nums.length];
left[0] = 1;
right[nums.length - 1] = 1;
for (int i = 1; i < nums.length; i++) {
left[i] = left[i - 1] * nums[i - 1];
}
for (int i = nums.length - 2; i >= 0; i--) {
right[i] = right[i + 1] * nums[i + 1];
}
for (int i = 0; i < left.length; i++) {
left[i] *= right[i];
}
return left;
}
}

View File

@ -20,7 +20,7 @@ public class T67_221_MaximalSquare {
{'1', '1', '1', '1', '1'},
{'1', '0', '0', '1', '0'}
};
System.out.println(maximalSquare(matrix));
System.out.println(maximalSquare1(matrix));
}
@Test
@ -76,4 +76,28 @@ public class T67_221_MaximalSquare {
return result;
}
public int maximalSquare1(char[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m][n];
int result = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == '1') {
if (i < 1 || j < 1) {
dp[i][j] = 1;//因为第一层最多只有1
} else {
dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;//值得注意的是添加了dp[i-1][j-1]
//因为正方形需要全是1而对角为0的情况可能可能会计算出同样的结果
}
result = Math.max(result, dp[i][j]);
}
}
}
return result * result;
}
}

View File

@ -0,0 +1,48 @@
package com.markilue.leecode.hot100.second;
import com.markilue.leecode.tree.TreeNode;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-25 10:31
*@Description: TODO 力扣236 二叉树的最近公共祖先
*@Version: 1.0
*/
public class T70_236_LowestCommonAncestor {
//思路:先遍历到谁,谁就一定是最大的其他的可能在子树上或者在另一个树上两者返回值都可以确定
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return root;
} else if (root == p) {
return p;
} else if (root == q) {
return q;
}
//全都没碰到:在当前节点的子树上
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {
return root;
}else if(left==null){
return right;
}else {
return left;
}
}
//优秀写法
public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {return root;}
return left != null ? left : right;
}
}

View File

@ -0,0 +1,43 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-25 10:39
*@Description: TODO 力扣238 除自身以外数组的乘积
*@Version: 1.0
*/
public class T71_238_ProductExceptSelf {
@Test
public void test() {
int[] nums = {1, 2, 3, 4};
System.out.println(Arrays.toString(productExceptSelf(nums)));
}
//思路:考虑分别使用一个left和right记录这个数左边数的乘积和右边数的乘积最后计算总和
//其实本题的矛盾点就在于:如果不想要当前就会损失前面的或者后面的就会瞻前顾后遍历两次即可
public int[] productExceptSelf(int[] nums) {
int[] left = new int[nums.length];
int[] right = new int[nums.length];
left[0] = 1;
right[nums.length - 1] = 1;
for (int i = 1; i < nums.length; i++) {
left[i] = left[i - 1] * nums[i - 1];
}
for (int i = nums.length - 2; i >= 0; i--) {
right[i] = right[i + 1] * nums[i + 1];
}
for (int i = 0; i < left.length; i++) {
left[i] *= right[i];
}
return left;
}
}

View File

@ -0,0 +1,63 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
import java.util.ArrayDeque;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-25 10:56
*@Description: TODO 力扣239 滑动窗口最大值
*@Version: 1.0
*/
public class T72_239_MaxSlidingWindow {
@Test
public void test(){
int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
int k = 3;
System.out.println(Arrays.toString(maxSlidingWindow(nums,k)));
}
@Test
public void test1(){
int[] nums = {1,-1};
int k = 1;
System.out.println(Arrays.toString(maxSlidingWindow(nums,k)));
}
//使用一个单调栈进行记录:定期排除过期元素
public int[] maxSlidingWindow(int[] nums, int k) {
ArrayDeque<int[]> stack = new ArrayDeque<>();//[num,index]
int[] result = new int[nums.length - k + 1];
//先入栈前k个确定result的第一个位置,以后每移动一位,result也赋值一位
for (int i = 0; i < k; i++) {
result[0] = Math.max(result[0], nums[i]);
while (!stack.isEmpty() && stack.peek()[0] < nums[i]) {
//在他前面,还比他小那么一定不用记录了
stack.pop();
}
stack.addFirst(new int[]{nums[i], i});
}
for (int i = k; i < nums.length; i++) {
//先清理掉尾部过期元素
while (!stack.isEmpty() && (i - stack.peekLast()[1]) >= k) {
//超过窗口了
stack.pollLast();
}
//将当前元素记录在stack中
while (!stack.isEmpty() && stack.peek()[0] < nums[i]) {
//在他前面,还比他小那么一定不用记录了
stack.pop();
}
stack.addFirst(new int[]{nums[i], i});
result[i - k + 1] = stack.peekLast()[0];
}
return result;
}
}

View File

@ -0,0 +1,40 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-25 11:31
*@Description: TODO 力扣240 搜索二维矩阵II
*@Version: 1.0
*/
public class T73_240_SearchMatrix {
@Test
public void test() {
int[][] nums = {{1, 1}};
System.out.println(searchMatrix(nums, 0));
}
//从左上角开始遍历:那么满足:target比当前值大则向下反之则向左
public boolean searchMatrix(int[][] matrix, int target) {
//左上角第一个数
int nowI = 0;
int nowJ = matrix[0].length - 1;
while (nowI < matrix.length && nowJ >= 0) {
if (matrix[nowI][nowJ] == target) {
return true;
} else if (matrix[nowI][nowJ] < target) {
nowI++;
} else {
nowJ--;
}
}
return false;
}
}

View File

@ -0,0 +1,32 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-05-25 11:42
*@Description: TODO 力扣279 完全平方数
*@Version: 1.0
*/
public class T74_279_NumSquares {
@Test
public void test() {
System.out.println(numSquares(12));
}
public int numSquares(int n) {
if (n < 1) return 0;
int[] dp = new int[n + 1];
dp[1] = 1;
for (int i = 2; i < dp.length; i++) {
dp[i] = i;//最多i个
for (int j = 1; j <= Math.sqrt(i); j++) {
dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
}
}
return dp[n];
}
}

View File

@ -30,6 +30,7 @@
目前,有四种类型的变换可用:
离散傅里叶变换DFT、离散余弦变换DCT、离散正弦变换DST和离散哈特利变换DHT-->
<!--使用教程:http://wendykierp.github.io/JTransforms/apidocs/-->
<!--经过测试,结果暂时不对-->
<dependency>
<groupId>com.github.wendykierp</groupId>
<artifactId>JTransforms</artifactId>

View File

@ -0,0 +1,22 @@
package com.cqu.algorithm.fft;
import java.util.List;
/**
*@BelongsProject: phm_parent
*@BelongsPackage: com.cqu.algorithm.fft
*@Author: markilue
*@CreateTime: 2023-05-24 15:24
*@Description: TODO 构建Complex数组
*@Version: 1.0
*/
public class BulidComplex {
public static Complex[] build(List<Double> raw) {
Complex[] complexes = new Complex[raw.size()];
for (int i = 0; i < complexes.length; i++) {
complexes[i] = new Complex(raw.get(i));
}
return complexes;
}
}

View File

@ -0,0 +1,82 @@
package com.cqu.algorithm.fft;
public class Complex {
//复数类实现复数的加减乘除以及重写toString方法
private double real;
private double image;
public Complex() {
this(0,0);
}
public Complex (double real) {
this(real,0);
}
public Complex(double real,double image) {
this.real = real;
this.image = image;
}
public Complex plus(Complex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
double newReal =real + real2;
double newImage =image + image2;
return new Complex(newReal,newImage);
}
public Complex minus(Complex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
double newReal =real - real2;
double newImage =image - image2;
return new Complex(newReal,newImage);
}
public Complex multiply(Complex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
double newReal = real * real2 - image * image2;
double newImage = image * real2 + real * image2;
return new Complex(newReal,newImage);
}
public Complex divide(Complex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
double newReal = (real*real2 + image*image2)/(real2*real2 + image2*image2);
double newImage = (image*real2 - real*image2)/(real2*real2 + image2*image2);
return new Complex(newReal,newImage);
}
//计算真实大小的时部和虚部
public Complex divide(int dim) {
real = real * 2 / dim;
image = image * 2 / dim;
return this;
}
//计算振幅
public double getAmplitude() {
return Math.sqrt(real * real + image * image);
}
public double getReal() {
return real;
}
public void setReal(double real) {
this.real = real;
}
public double getImage() {
return image;
}
public void setImage(double image) {
this.image = image;
}
@Override
public String toString() {
return "real=" + real + ", image=" + image;
}
}

View File

@ -0,0 +1,31 @@
package com.cqu.algorithm.fft;
/**
*@BelongsProject: phm_parent
*@BelongsPackage: com.cqu.algorithm.fft
*@Author: markilue
*@CreateTime: 2023-05-24 15:24
*@Description: TODO DFT算法的实现类
*@Version: 1.0
*/
public class DFT {
//DFT计算
public static Complex[] dft(Complex[] x,int N) {
if(N == 1 || x.length == 1) {
return x;
}
Complex result[] = new Complex[N];
for(int k = 0; k < N; k++) {
result[k] = new Complex();
for(int n = 0; n<N; n++) {
double W = -2*n*k*Math.PI/N;
Complex c = new Complex(Math.cos(W),Math.sin(W));
result[k] = result[k].plus(x[n].multiply(c));
}
}
return result;
}
}

View File

@ -1,25 +1,148 @@
package com.cqu.algorithm.fft;
import org.jtransforms.fft.BenchmarkDoubleFFT;
import org.jtransforms.fft.BenchmarkFloatFFT;
import org.jtransforms.fft.DoubleFFT_1D;
import java.io.IOException;
/**
*@BelongsProject: phm_parent
*@BelongsPackage: com.cqu.algorithm.fft
*@Author: markilue
*@CreateTime: 2023-05-23 20:19
*@Description: TODO FFT
*@CreateTime: 2023-05-24 15:24
*@Description: TODO FFT算法的实现类
*@Version: 1.0
*/
public class FFT {
public static Complex[] fft(Complex[] x,int N) {
//定义式计算FFT方法一
if(N == 1 ) {
return x;
}
// 如果信号数为奇数使用dft计算
if(N % 2 != 0) {
return DFT.dft(x, N);
}
// 提取下标为偶数的原始信号值进行递归fft计算
Complex[] even = new Complex[N / 2];
for (int k = 0; k < even.length; k++) {
even[k] = x[2 * k];
}
Complex[] evenValue = FFT.fft(even, even.length);
public static void main(String[] args) throws IOException {
new DoubleFFT_1D(10).complexForward(new double[10]);
// 提取下标为奇数的原始信号值进行fft计算
// 节约内存
Complex[] odd = even;
for (int k = 0; k < odd.length; k++) {
odd[k] = x[2 * k + 1];
}
Complex[] oddValue = FFT.fft(odd,odd.length);
// 偶数+奇数
Complex[] result = new Complex[N];
for (int k = 0; k < N / 2; k++) {
double W = -2*k*Math.PI/N;
Complex m = new Complex(Math.cos(W), Math.sin(W));
result[k] = evenValue[k].plus(m.multiply(oddValue[k]));
result[k + N / 2] = evenValue[k].minus(m.multiply(oddValue[k]));
}
return result;
}
public static void reverse(Complex[] A,int N) {
//倒叙前N个数据
int LH = N/2;
int J = LH;
int N1 = N-2;
for(int I = 1;I <= N1; I++) {
if(!(I >=J)) {
Complex T = A[I];
A[I] = A[J];
A[J] = T;
}
int K = LH;
while(!(J < K)) {
J = J - K;
K = K/2;
}
J += K;
}
// return null;
}
//对复数数组倒叙
public static void reverse(Complex[] A) {
int N = A.length;
int LH = N/2;
int J = LH;
int N1 = N-2;
for(int I = 1;I <= N1; I++) {
if(!(I >=J)) {
Complex T = A[I];
A[I] = A[J];
A[J] = T;
}
int K = LH;
while(!(J < K)) {
J = J - K;
K = K/2;
}
J += K;
}
// return null;
}
public static Complex[] myFFT(Complex[] A,int N) {
//FFT计算方法二推荐这一种错误小
int M = returnM(N);
Complex[] x = new Complex[N];
System.arraycopy(A, 0, x, 0, N);
reverse(x);
for(int L = 1;L <= M;L++) {
int B = (int)Math.pow(2, L-1);
for(int J = 0;J <= B-1;J++) {
int P = (int)Math.pow(2, M-L)*J;
for(int k = J;k <= N-1;k += Math.pow(2, L)) {
double W = -2*Math.PI*P/N;
Complex c = x[k+B].multiply(new Complex(Math.cos(W),Math.sin(W)));
Complex T = x[k].plus(c);
x[k+B] = x[k].minus(c);
x[k] = T;
}
}
}
return x;
}
public static Complex[] myFFT(Complex[] A,int offset,int N) {
//FFT计算计算从offset开始的N条数据
int M = returnM(N);
Complex[] x = new Complex[N];
System.arraycopy(A, offset, x, 0, N);
reverse(x);
for(int L = 1;L <= M;L++) {
int B = (int)Math.pow(2, L-1);
for(int J = 0;J <= B-1;J++) {
int P = (int)Math.pow(2, M-L)*J;
for(int k = J;k <= N-1;k += Math.pow(2, L)) {
double W = -2*Math.PI*P/N;
Complex c = x[k+B].multiply(new Complex(Math.cos(W),Math.sin(W)));
Complex T = x[k].plus(c);
x[k+B] = x[k].minus(c);
x[k] = T;
}
}
}
return x;
}
//返回一个数是2的几次幂
public static int returnM(int N) {
// int N = x.length;
if((N&(N-1))!=0) {
throw new RuntimeException("非2的整数幂");
}
int M=0;
while((N = N / 2) != 0) {
M++;
}
return M;
}
}

View File

@ -0,0 +1,99 @@
package com.cqu.algorithm.fft;
import javax.print.DocFlavor;
/**
*@BelongsProject: phm_parent
*@BelongsPackage: com.cqu.algorithm.fft
*@Author: markilue
*@CreateTime: 2023-05-24 15:24
*@Description:
* TODO 每一个点的复数类real表示实数;image表示虚数
* 使用函数式编程接口:加减乘除都改变自身
*@Version: 1.0
*/
public class MutableComplex {
//复数类实现复数的加减乘除以及重写toString方法
private double real;
private double image;
public MutableComplex() {
this(0, 0);
}
public MutableComplex(double real) {
this(real, 0);
}
public MutableComplex(double real, double image) {
this.real = real;
this.image = image;
}
public MutableComplex plus(MutableComplex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
real = real + real2;
image = image + image2;
return this;
}
public MutableComplex minus(MutableComplex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
real = real - real2;
image = image - image2;
return this;
}
public MutableComplex multiply(MutableComplex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
real = real * real2 - image * image2;
image = image * real2 + real * image2;
return this;
}
public MutableComplex divide(MutableComplex complex) {
double real2 = complex.getReal();
double image2 = complex.getImage();
real = (real * real2 + image * image2) / (real2 * real2 + image2 * image2);
image = (image * real2 - real * image2) / (real2 * real2 + image2 * image2);
return this;
}
//计算真实大小的时部和虚部
public MutableComplex divide(int dim) {
real = real * 2 / dim;
image = image * 2 / dim;
return this;
}
public double getReal() {
return real;
}
public void setReal(double real) {
this.real = real;
}
public double getImage() {
return image;
}
public void setImage(double image) {
this.image = image;
}
//计算振幅
public double getAmplitude() {
return Math.sqrt(real * real + image * image);
}
@Override
public String toString() {
return "real=" + real + ", image=" + image;
}
}

View File

@ -0,0 +1,15 @@
package com.cqu.algorithm.fft;
import java.math.BigDecimal;
/**
* 测试
*/
public class TestComplex {
//测试复数运算
public static void main(String[] args) {
Complex complex1 = new Complex(5);
Complex complex2 = new Complex(4);
System.out.println(complex1.multiply(complex2));
}
}

View File

@ -0,0 +1,76 @@
package com.cqu.algorithm.fft;
import java.util.Arrays;
/**
* 测试FFT
*/
public class TestFFT {
//测试DFTFFT运算
public static void main(String[] args) {
// TODO Auto-generated method stub
// test1();
test3();
}
public static void test1() {
Complex[] x = new Complex[5];
x[0] = new Complex(4);
x[1] = new Complex(3);
x[2] = new Complex(2);
x[3] = new Complex(1);
x[4] = new Complex(0);
for(Complex a:x) {
System.out.println(a);
}
Complex[] x1 = DFT.dft(x, 5);
for(Complex a:x1) {
System.out.println(a);
}
}
public static void test2() {
Complex[] x = new Complex[8];
for(int i = 0;i < x.length;i++) {
x[i] = new Complex(i);
}
for(Complex a:x) {
System.out.println(a);
}
Complex[] x1 = DFT.dft(x, 8);
Complex[] x2 = FFT.fft(x, 8);
Complex[] x3 = FFT.myFFT(x, 8);
for (int i = 0; i < x3.length; i++) {
System.out.println(x1[i] + "/" + x2[i] + "/" + x3[i]);
}
}
public static void test3() {
Complex[] x = BulidComplex.build(Arrays.asList(-0.029078494757,
-0.33095228672,
-0.12124221772,
0.553512275219,
-0.158036053181,
0.268739402294,
-0.638222515583,
0.233140587807,
-0.173265621066,
0.467218101025,
-0.372010827065,
-0.136630430818,
0.343256533146,
0.008932195604));
for(Complex a:x) {
System.out.println(a);
}
Complex[] x1 = DFT.dft(x, 14);
Complex[] x2 = FFT.fft(x, 14);
// Complex[] x3 = FFT.myFFT(x, 14);
for (int i = 0; i < x2.length; i++) {
System.out.println(x1[i] + "/" + x2[i]);
}
}
}

View File

@ -29,6 +29,7 @@ public abstract class BaseStreamApp {
env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3, 3000L));
env.setStateBackend(new FsStateBackend(PHMConfig.RT_CHECKPOINT_LOCATION));
System.setProperty("HADOOP_USER_NAME", PHMConfig.HADOOP_USER_NAME);
System.setProperty("java.vm.name","Java HotSpot(TM) ");//使用的JDK版本
//模板
execute(env);
env.execute();

View File

@ -5,7 +5,9 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqu.warehouse.realtime.app.base.BaseStreamApp;
import com.cqu.warehouse.realtime.app.func.DataSamplingFunction;
import com.cqu.warehouse.realtime.app.func.FFTSamplingFunction;
import com.cqu.warehouse.realtime.utils.MyKafkaUtils;
import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.functions.RichMapFunction;
@ -200,6 +202,10 @@ public class WindCMSApp extends BaseStreamApp {
@Override
public void process(Tuple2<String, String> stringStringTuple2, ProcessWindowFunction<JSONObject, JSONObject, Tuple2<String, String>, TimeWindow>.Context context, Iterable<JSONObject> iterable, Collector<JSONObject> collector) throws Exception {
JSONObject obj = null;
//参考:https://zhuanlan.zhihu.com/p/534376156
//经过测试:1000个点一发:iterable500M
//10000个点一发:iterable370M
System.out.println("iterable_data_size:" + ObjectSizeCalculator.getObjectSize(iterable));
for (JSONObject jsonObject : iterable) {
if (obj == null) {
obj = jsonObject;
@ -212,15 +218,40 @@ public class WindCMSApp extends BaseStreamApp {
}
}
);
//TODO 合并的结果大概有10000个数据:判断是否合理
mergeDS.print(">>>");
//TODO 5.写回kafka
mergeDS
.map(jsonObject -> jsonObject.toJSONString())
.addSink(
MyKafkaUtils.getKafkaSink("dwm_wind_cms_10_downsampling")
//TODO 6.计算频谱 --不知道要计算多久,使用异步Stream进行计算
SingleOutputStreamOperator<JSONObject> fftDS = AsyncDataStream.unorderedWait(
mergeDS,
new FFTSamplingFunction<JSONObject>() {
@Override
protected void setTransformData(JSONObject jsonObject, List<Double> fft) {
jsonObject.put("x", fft);
}
@Override
protected List<Double> getTransformData(JSONObject jsonObject) {
return jsonObject.getJSONArray("x").toJavaList(Double.class);
}
},
60, TimeUnit.SECONDS
);
//TODO 合并的结果大概有10000个数据:判断是否合理
mergeDS.print(">>>");
// fftDS.print(">>>");
//TODO 5.写回kafka
// mergeDS
// .map(jsonObject -> jsonObject.toJSONString())
// .addSink(
// MyKafkaUtils.getKafkaSink("dwm_wind_cms_10_downsampling")
// );
// fftDS
// .map(jsonObject -> jsonObject.toJSONString())
// .addSink(
// MyKafkaUtils.getKafkaSink("dwm_wind_cms_10_frequency")
// );
}
}

View File

@ -0,0 +1,34 @@
package com.cqu.warehouse.realtime.app.func;
import com.cqu.warehouse.realtime.utils.TransformUtils;
import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
import org.apache.flink.streaming.api.functions.async.AsyncFunction;
import org.apache.flink.streaming.api.functions.async.ResultFuture;
import java.util.Collections;
import java.util.List;
/**
*@BelongsProject: phm_parent
*@BelongsPackage: com.cqu.warehouse.realtime.app.func
*@Author: markilue
*@CreateTime: 2023-05-24 17:46
*@Description: TODO 计算数据的FFT
*@Version: 1.0
*/
public abstract class FFTSamplingFunction<T> implements AsyncFunction<T, T> {
@Override
public void asyncInvoke(T t, ResultFuture<T> resultFuture) throws Exception {
List<Double> transformData = getTransformData(t);
List<Double> fft = TransformUtils.fft(transformData);
setTransformData(t,fft);
System.out.println("fftDataSize:"+ObjectSizeCalculator.getObjectSize(t));
resultFuture.complete(Collections.singleton(t));
}
protected abstract void setTransformData(T t, List<Double> fft);
protected abstract List<Double> getTransformData(T t);
}

View File

@ -1,8 +1,12 @@
package com.cqu.warehouse.realtime.utils;
import com.cqu.algorithm.fft.Complex;
import com.cqu.algorithm.fft.FFT;
import org.jtransforms.dct.DoubleDCT_1D;
import org.jtransforms.fft.DoubleFFT_1D;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@ -16,21 +20,59 @@ import java.util.List;
* 2)DCT
* 3)DST
* 4)DHT
* 参考: <!--使用教程:http://wendykierp.github.io/JTransforms/apidocs/-->
*@Version: 1.0
*/
public class TransformUtils {
public static void fft(double[] data) {
new DoubleFFT_1D(data.length).complexForward(data);
private static Complex[] buildComplex(double[] raw) {
Complex[] complexes = new Complex[raw.length];
for (int i = 0; i < complexes.length; i++) {
complexes[i] = new Complex(raw[i]);
}
return complexes;
}
public static double[] fft(List<Double> data) {
double[] raw = new double[data.size()];
for (int i = 0; i < raw.length; i++) {
raw[i] = data.get(i);
private static Complex[] buildComplex(List<Double> raw) {
Complex[] complexes = new Complex[raw.size()];
for (int i = 0; i < complexes.length; i++) {
complexes[i] = new Complex(raw.get(i));
}
// fft(data.toArray(new Double[0]));
fft(raw);
return raw;
return complexes;
}
public static List<Double> fft(double[] data) {
Complex[] raw = buildComplex(data);
Complex[] fft = FFT.fft(raw, raw.length);
return calculateAmplitude(fft);
}
public static List<Double> fft(List<Double> data) {
Complex[] raw = buildComplex(data);
Complex[] fft = FFT.fft(raw, raw.length);
return calculateAmplitude(fft);
}
private static List<Double> calculateAmplitude(Complex[] fft) {
List<Double> amplitudeList = new ArrayList<>();
for (Complex complex : fft) {
amplitudeList.add(complex.divide(fft.length).getAmplitude());
}
return amplitudeList;
}
public static void main(String[] args) {
double[] array = {-0.029078494757, -0.33095228672, -0.12124221772, 0.553512275219, -0.158036053181,
0.268739402294,
-0.638222515583,
0.233140587807,
-0.173265621066,
0.467218101025,
-0.372010827065,
-0.136630430818,
0.343256533146,
0.008932195604};
List<Double> fft = fft(array);
System.out.println(fft);
}
}