This commit is contained in:
whai 2024-04-04 17:06:59 +08:00
parent 1044629a5e
commit d8c1950a6b
17 changed files with 1390 additions and 7 deletions

View File

@ -9,14 +9,19 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency> <dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId> <artifactId>hutool-http</artifactId>

View File

@ -0,0 +1,468 @@
package cn.whaifree.interview.tx;
import cn.whaifree.leetCode.model.ListNode;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/31 19:55
* @注释
*/
public class tx01 {
// public volatile Integer single = null;
//
// public Integer getSingle() {
// if (single == null) {
// synchronized (Integer.class) {
// if (single == null) {
// return new Integer(1);
// }
// }
// }
// return null;
// }
static class c extends Thread{
@Override
public void run() {
System.out.println("c");
}
}
public static void main(String[] args) {
new c().start();
Runnable runnable = () -> {
System.out.println("1");
};
Callable<Object> objectCallable = new Callable<>() {
@Override
public Object call() throws Exception {
System.out.println("call");
return null;
}
};
FutureTask<Object> objectFutureTask = new FutureTask<>(objectCallable);
new Thread(objectFutureTask).start();
}
static class p1 {
/**
* 小红拿到了一个无向图其中一些边被染成了红色
* 小红定义一个点是好点当且仅当这个点的所有邻边都是红边
* 现在请你求出这个无向图好点的数量
* 如果一个节点没有任何邻边那么它也是好点
* <p>
* 输入描述
* 第一行输入两个正整数n,m代表节点的数量和边的数量
* 接下来的m行每行输入两个正整数u,v和一个字符chr代表节点u和节点v有一条边连接如果 chr 'R'代表这条边被染红'W'代表未被染色
* <p>
* 1\leq n,m \leq 10^5
* 1\leq u,v \leq n
* <p>
* 输出描述
* 一个整数代表好点的数量
* <p>
* 示例 1
* 收起
* <p>
* 输入
* 复制
* 4 4
* 1 2 R
* 2 3 W
* 3 4 W
* 1 4 R
* 输出
* 复制
* 1
* 说明
* 只有 1 号节点是好点
*
* @param args
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
HashMap<Integer, List<int[]>> map = new HashMap<>();
for (int i = 0; i < m; i++) {
int a = scanner.nextInt();
int b = scanner.nextInt();
String next = scanner.next();
if (next.equals("R")) {
if (!map.containsKey(a)) {
map.put(a, new ArrayList<>());
}
map.get(a).add(new int[]{b, 1});
if (!map.containsKey(b)) {
map.put(b, new ArrayList<>());
}
map.get(b).add(new int[]{a, 1});
} else {
if (!map.containsKey(a)) {
map.put(a, new ArrayList<>());
}
map.get(a).add(new int[]{b, 0});
if (!map.containsKey(b)) {
map.put(b, new ArrayList<>());
}
map.get(b).add(new int[]{a, 0});
}
}
int res = 0;
Set<Integer> integers = map.keySet();
for (Integer key : integers) {
boolean flag = true;
List<int[]> ints = map.get(key);
for (int[] anInt : ints) {
if (anInt[1] == 0) {
flag = false;
break;
}
}
if (flag) res++;
}
// 对没有边的
res += (n - integers.size());
System.out.println(res);
}
}
static class p2 {
/**
* 小红拿到了一个链表她准备将这个链表断裂成两个链表再拼接到一起使得链表从头节点到尾部升序你能帮小红判断能否达成目的吗
* 给定的为一个链表数组你需要对于数组中每个链表进行一次或者的答案回答并返回布尔数组
* 每个链表的长度不小于 2且每个链表中不包含两个相等的元素所有链表的长度之和保证不超过10^5
* <p>
* 示例 1
* 收起
* <p>
* 输入
* 复制
* [{1,2,3},{2,3,1},{3,2,1}]
* 输出
* 复制
* [true,true,false]
* 说明
* 第三个链表无论怎么操作都不满足条件
*
* @param args
*/
public static void main(String[] args) {
System.out.println(cansort(ListNode.listNodeFromArray(new int[]{1, 2, 3})));
}
public boolean[] canSorted(ListNode[] lists) {
// write code here
boolean[] res = new boolean[lists.length];
for (int i = 0; i < lists.length; i++) {
boolean cansort = cansort(lists[i]);
res[i] = cansort;
}
return res;
}
public static boolean cansort(ListNode node) {
// 4 6 1 3 2 找到两个区间都递增
ListNode index = node;
int flag = 0;
while (index.next != null) {
if (index.val > index.next.val) {
if (index.next.next != null && index.next.next.val > index.val) {
return false;
}
if (flag == 1) return false;
flag = 1;
}
index = index.next;
}
return true;
}
}
static class p4 {
/**
* 小红拿到了一个有 n 个节点的无向图这个图初始并不是连通图
* 现在小红想知道添加恰好一条边使得这个图连通有多少种不同的加边方案
* <p>
* 输入描述
* 第一行输入两个正整数n,m用空格隔开
* 接下来的m行每行输入两个正整数u,v代表节点u和节点v之间有一条边连接
* 1\leq n,m \leq 10^5
* 1\leq u,v \leq n
* 保证给出的图是不连通的
* <p>
* 输出描述
* 一个整数代表加边的方案数
* <p>
* 示例 1
* 收起
* <p>
* 输入
* 复制
* 4 2
* 1 2
* 3 4
* 输出
* 复制
* 4
* 说明
* 添加边 (1,3) 或者 (1,4) 或者 (2,3) 或者 (2,4) 都是可以的
* <p>
* 示例 2
* 收起
* <p>
* 输入
* 复制
* 4 1
* 1 3
* 输出
* 复制
* 0
* 说明
* 无论添加哪条边都不可能使得该图变成连通图
*
* @param args
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
HashSet<Integer> set1 = new HashSet<>();
HashSet<Integer> set2 = new HashSet<>();
int a = scanner.nextInt();
int b = scanner.nextInt();
set1.add(a);
set1.add(b);
for (int i = 1; i < m; i++) {
a = scanner.nextInt();
b = scanner.nextInt();
if ((set1.contains(a) || set1.contains(b))) {
set1.add(a);
set1.add(b);
} else {
set2.add(a);
set2.add(b);
}
}
System.out.println(set1.size() * set2.size());
}
}
static class p5 {
/**
* 小红拿到了一个数组她准备将数组分割成 k 使得每段内部做按位异或后再全部求和小红希望最终这个和尽可能大你能帮帮她吗
* <p>
* 输入描述
* 输入包含两行
* 第一行两个正整数 n, k , (1\leq k \leq n \leq 400)分别表示数组的长度和要分的段数
* 第二行 n 个整数 a_i (0 \leq a_i \leq 10^9)表示数组 a 的元素
* <p>
* 输出描述
* 输出一个正整数表示最终的最大和
* <p>
* 示例 1
* 收起
* <p>
* 输入
* 复制
* 6 2
* 1 1 1 2 3 4
* 输出
* 复制
* 10
* 说明
* 小红将数组分为了
* [1, 4] [5, 6] 这两个区间得分分别为1 \oplus 1 \oplus 1 \oplus 2 = 3 3 \oplus 4 = 7总得分为 3+7=10
* 可以证明不存在比 10 更优的分割方案
* \oplus 符号表示异或操作
* <p>
* 示例 2
* 收起
* <p>
* 输入
* 复制
* 5 3
* 1 0 1 1 0
* 输出
* 复制
* 3
* 示例 3
* 收起
* <p>
* 输入
* 复制
* 3 3
* 1 1 2
* 输出
* 复制
* 4
*
* @param args
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = scanner.nextInt();
}
}
public static int maxXorSum(int[] nums, int k) {
int n = nums.length;
int[][] prefixXor = new int[n + 1][k + 1];
int[][] dp = new int[n + 1][k + 1];
// 计算前缀异或和
for (int i = 1; i <= n; i++) {
prefixXor[i][0] = prefixXor[i - 1][0] ^ nums[i - 1];
}
for (int j = 1; j <= k; j++) {
for (int i = 1; i <= n; i++) {
prefixXor[i][j] = prefixXor[i][0];
dp[i][j] = dp[i - 1][j];
for (int x = 0; x < i; x++) {
dp[i][j] = Math.max(dp[i][j], dp[x][j - 1] + prefixXor[i][j]);
}
}
}
return dp[n][k];
}
}
static class p6 {
static int res = 0;
static List<Character> path = null;
/**
* 小红拿到了一个字符矩阵她可以从任意一个地方出发希望走 6 步后恰好形成"tencent"字符串小红想知道共有多少种不同的行走方案
* 每一步可以选择上右中任意一个方向进行行走不可行走到矩阵外部
* <p>
* 输入描述
* 第一行输入两个正整数n,m代表矩阵的行数和列数
* 接下来的n行每行输入一个长度为m的仅由小写字母组成的字符串代表小红拿到的矩阵
* <p>
* 1\leq n,m \leq 1000
* <p>
* 输出描述
* 一个整数代表最终合法的方案数
* <p>
* 示例 1
* 收起
* <p>
* 输入
* 复制
* 3 3
* ten
* nec
* ten
* 输出
* 复制
* 4
* 说明
* 第一个方案从左上角出发右右下左左上
* 第二个方案从左上角出发右右下左左下
* 第三个方案从左下角出发右右上左左下
* 第四个方案从左上角出发右右上左左上
*
* @param args
*/
public static void main(String[] args) {
path = new ArrayList<>();
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
char[][] chars = new char[n][m];
for (int i = 0; i < n; i++) {
char[] c = scanner.next().toCharArray();
for (int j = 0; j < c.length; j++) {
chars[i][j] = c[j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (chars[i][j] == 't') {
path.add('t');
backing(chars, i, j);
path.remove(path.size() - 1);
}
}
}
System.out.println(res);
}
public static void backing(char[][] chars, int x, int y) {
if (path.size() == 7) {
// System.out.println(new ArrayList<>(path));
res++;
return;
}
Character expect = null;
if (path.size() == 1) {
expect = 'e';
} else if (path.size() == 2) {
expect = 'n';
} else if (path.size() == 3) {
expect = 'c';
} else if (path.size() == 4) {
expect = 'e';
} else if (path.size() == 5) {
expect = 'n';
} else if (path.size() == 6) {
expect = 't';
}
path.add(chars[x][y]);
if (x < chars.length - 1 && expect.equals(chars[x + 1][y])) {
backing(chars, x + 1, y);
}
if (y < chars[0].length - 1 && expect.equals(chars[x][y + 1])) {
backing(chars, x, y + 1);
}
if (x > 0 && expect.equals(chars[x - 1][y])) {
backing(chars, x - 1, y);
}
if (y > 0 && expect.equals(chars[x][y - 1])) {
backing(chars, x, y - 1);
}
path.remove(path.size() - 1);
}
}
}

View File

@ -0,0 +1,88 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/3 14:38
* @注释
*/
public class LeetCode121 {
@Test
public void test()
{
int[] prices = {7,1,5,3,6,4};
System.out.println(new Solution1().maxProfit(prices));
}
class Solution {
/**
*
* 只能选择 某一天 买入这只股票并选择在 未来的某一个不同的日子 卖出该股票
*
* dp[i][1]表示i天不持有股票的持有现金
* dp[i][0]表示i天持有股票所有的现金
* 第i天买入股票现金就是 -prices[i]
*
* 第i天有股票 1. 刚刚买入2. 第i-1天就有
* 第i天没有股票 2. 第i天卖出 2. 第i-1天就没有股票
*
* dp[i][0] 持有股票
* - i-1就持有股票今天不卖 dp[i-1][0]
* - 买入股票 -今天的股价 -prices[i]
* - max
* dp[i][1] 无持有
* - i-1 保持现状dp[i-1][1]
* - 卖出 prices[i] + dp[i-1][0] 价格+[i-1]天加持有的现金
* - max
* dp[0][0] = -price[0]
* dp[0][1] = 0
*
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
if (prices.length == 1) {
return 0;
}
int[] dp = new int[2];
dp[0] = -prices[0];
dp[1] = 0;
for (int i = 0; i < prices.length; i++) {
// 持有股票 1. i-1就有 2. 刚刚买入
dp[0] = Math.max(dp[0], -prices[i]);
// 无股票 2. i-1就无2 刚刚卖出
dp[1] = Math.max(dp[1], dp[0] + prices[i]);
}
return dp[1]; // 最后一天一定没有股票才能有最大利润
}
}
class Solution1 {
/**
* 贪心
* @param prices
* @return
*/
public int maxProfit(int[] prices) {
int min = Integer.MAX_VALUE;
int res = 0;
for (int i = 0; i < prices.length; i++) {
min = Math.min(min, prices[i]);
res = Math.max(res, prices[i] - min);
}
return res;
}
}
}

View File

@ -0,0 +1,40 @@
package cn.whaifree.leetCode.Dynamic;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/3 13:50
* @注释
*/
public class LeetCode198 {
@Test
public void test()
{
Solution solution = new Solution();
int[] nums = new int[]{2,7};
int rob = solution.rob(nums);
System.out.println(rob);
}
class Solution {
public int rob(int[] nums) {
if (nums.length == 1) {
return nums[0];
}
// dp[i] 表示 从0-i偷窃都最大价值
// dp[i] = max(dp[i-1],dp[i-2]+nums[i]])
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[nums.length - 1];
}
}
}

View File

@ -13,9 +13,9 @@ import java.util.Arrays;
public class LeetCode322 { public class LeetCode322 {
@Test @Test
public void test() { public void test() {
int[] coins = {1,2,5}; int[] coins = {1};
int amount = 11; int amount = 0;
int i = new Solution().coinChange(coins, amount); int i = new Solution1().coinChange(coins, amount);
System.out.println(i); System.out.println(i);
} }
@ -44,4 +44,49 @@ public class LeetCode322 {
} }
} }
class Solution1 {
/**
* 背包容量为amount
* coins里随便取
*
* dp[j] 表示使用[0-i]任意硬币取凑出j的最小硬币数
*
* [1, 2, 5]
* 0 1 2 3 4 5 6
* 0 0 1 2 3 4 5 6
* 1 0 1 1 2 2 3 3
* 2
* 3
* 4
*
* dp[j] = math.min(dp[j],dp[j-coin[i]]+1)
*
* @param coins
* @param amount
* @return
*/
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
for (int i = 1; i < dp.length; i++) {
dp[i] = Integer.MAX_VALUE;
}
dp[0] = 0;
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j < amount + 1; j++) {
if (dp[j - coins[i]] != Integer.MAX_VALUE) {
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
}
} }

View File

@ -0,0 +1,71 @@
package cn.whaifree.leetCode.Dynamic;
import cn.whaifree.leetCode.model.TreeNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/3 13:55
* @注释
*/
public class LeetCode337 {
@Test
public void test()
{
System.out.println(new Solution().rob(TreeNode.constructTreeByArray(4,1,null,2,null,3)));
}
class Solution {
public int rob(TreeNode root) {
/**
* dp[0]表示不选该点的最大收益 dp[1]表示选该节点的最大收益
*
*/
int[] ints = robDown(root);
return Math.max(ints[0], ints[1]);
}
public int[] robDown(TreeNode root) {
int res[] = new int[2];
if (root == null) {
return res;
}
int[] left = robDown(root.left);
int[] right = robDown(root.right);
// 不偷Max(左孩子不偷左孩子偷) + Max(右孩子不偷右孩子偷)
// 不偷左右随意选最大的
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
// 左孩子不偷+ 右孩子不偷 + 当前节点偷
// 必须保证左右都不偷
res[1] = left[0] + right[0] + root.val;
return res;
}
}
class Solution1 {
public int rob(TreeNode root) {
// 两层根节点用和不用
return Math.max(robDown(root, true), robDown(root, false));
}
public int robDown(TreeNode root, boolean flag) {
if (root == null) {
return 0;
}
int left = robDown(root.left, !flag);
int right = robDown(root.right, !flag);
if (flag) {
return left + right + root.val;
}else {
return left + right;
}
}
}
}

View File

@ -98,4 +98,7 @@ public class LeetCode377 {
} }
} }

View File

@ -2,8 +2,8 @@ package cn.whaifree.leetCode.Hash;
import org.junit.Test; import org.junit.Test;
import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
/** /**
* 1. 两数之和 * 1. 两数之和
@ -39,7 +39,7 @@ import java.util.HashSet;
* *
* 进阶你可以想出一个时间复杂度小于 O(n2) 的算法吗 * 进阶你可以想出一个时间复杂度小于 O(n2) 的算法吗
*/ */
public class LeetCode1 { public class LeetCode1 implements Serializable {
@Test @Test
public void test() { public void test() {

View File

@ -0,0 +1,51 @@
package cn.whaifree.leetCode.LeetCode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/3 17:35
* @注释
*/
public class LeetCode11 {
@Test
public void test() {
Solution solution = new Solution();
int[] height = {1,1};
int i = solution.maxArea(height);
System.out.println(i);
}
class Solution {
/**
* $S(i,j)=min(h[i],h[j])*(j-i)$
* 双指针
* 长板移动面积不变或 变小
* 短板移动 变大 或不变
* 不断移动短板
* @param height
* @return
*/
public int maxArea(int[] height) {
int storage = 0;
int left = 0;
int right = height.length - 1;
while (left < right) {
storage = Math.max(getArea(height, left, right), storage);
if (height[left] < height[right]) {
left++;
}else {
right--;
}
}
return storage;
}
public int getArea(int[] height, int start, int end) {
return Math.min(height[start], height[end]) * (end - start);
}
}
}

View File

@ -0,0 +1,115 @@
package cn.whaifree.leetCode.LeetCode;
import org.junit.Test;
import java.util.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/4 13:44
* @注释
*/
public class LeetCode22 {
@Test
public void test() {
List<String> res =new Solution1().generateParenthesis(3);
System.out.println(res);
}
class Solution {
List<String> res = new ArrayList<>();
StringBuilder path = new StringBuilder();
/**
*
* @param n
* @return
*/
public List<String> generateParenthesis(int n) {
backTracking(n, 0, 0);
return res;
}
/**
*
* @param n
* @param leftCount 左括号用了几个
* @param rightCount 右括号用了几个
*/
public void backTracking(int n, int leftCount , int rightCount) {
if (leftCount > n || rightCount > leftCount) {
return;
}
if (path.length() == n * 2) {
res.add(path.toString());
return;
}
path.append("(");
backTracking(n, leftCount + 1, rightCount);
path.deleteCharAt(path.length() - 1); // 回溯
path.append(")");
backTracking(n, leftCount, rightCount + 1);
path.deleteCharAt(path.length() - 1); // 回溯
}
}
class Solution1 {
List<String> res = new ArrayList<>();
StringBuilder path = new StringBuilder();
/**
*
* @param n
* @return
*/
public List<String> generateParenthesis(int n) {
backTracking(n, n, n);
return res;
}
/**
*
* @param n
* @param leftCount 左括号可用数
* @param rightCount 右括号可用数
*/
public void backTracking(int n, int leftCount , int rightCount) {
if (leftCount == 0 && rightCount == 0) {
res.add(path.toString());
return;
}
if (leftCount > rightCount) {
return;
}
if (leftCount > 0) {
path.append("(");
backTracking(n, leftCount - 1, rightCount);
path.deleteCharAt(path.length() - 1);
}
if (rightCount > 0) {
path.append(")");
backTracking(n, leftCount, rightCount - 1);
path.deleteCharAt(path.length() - 1);
}
}
}
}

View File

@ -0,0 +1,79 @@
package cn.whaifree.leetCode.LinkedList;
import cn.whaifree.leetCode.model.ListNode;
import org.junit.Test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/4 13:05
* @注释
*/
public class LeetCode21 {
@Test
public void test() {
new Solution1().mergeTwoLists(
ListNode.listNodeFromArray(new int[]{5}),
ListNode.listNodeFromArray(new int[]{1, 2, 4})
).printList();
}
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list2 == null) {
return list1;
}
if (list1 == null) {
return list2;
}
ListNode pre = new ListNode(-1); // 标记结果头部
ListNode preIndex = pre; // 标记需要添加的位置
// 合并有序链表
ListNode indexA = list1;
ListNode indexB = list2;
while (indexA != null && indexB != null) {
if (indexA.val <= indexB.val) {
preIndex.next = indexA;
indexA = indexA.next;
}else {
preIndex.next = indexB;
indexB = indexB.next;
}
preIndex = preIndex.next;
}
if (indexA == null) {
preIndex.next = indexB;
}else {
preIndex.next = indexA;
}
return pre.next;
}
}
class Solution1 {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
if (list1.val < list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
}else {
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
}
}
}

View File

@ -0,0 +1,150 @@
package cn.whaifree.test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/3/23 20:36
* @注释
*/
public class CRC16_ARC {
private static final int CRC16_ARC = 0x8005; // CRC16-ARC多项式
/**
* 计算CRC16ARC校验值
* @param data 要计算校验值的数据数组
* @return 返回计算得到的CRC16ARC校验值
*/
public static int calculateCRC16ARC(byte[] data) {
// 使用CRC32算法计算校验值然后将其转换为16位
int crcValue = 0xFFFF; // 初始值为0xFFFF表示CRC16-ARC的初始寄存器状态
// 遍历数据数组逐字节计算CRC校验值
for (byte b : data) {
crcValue ^= b & 0xFF; // 将数据字节与CRC值异或
// 对CRC值进行8次位运算模拟移位和异或过程
for (int i = 0; i < 8; i++) {
if ((crcValue & 0x0001) != 0) {
crcValue = (crcValue >> 1) ^ CRC16_ARC; // 如果最低位为1进行异或运算
} else {
crcValue >>= 1; // 如果最低位为0仅右移一位
}
}
}
return crcValue;
}
/**
* 为指定的源文件附加CRC16ARC校验值并将结果保存为新文件
*
* @param sourceFilePath 源文件路径将对此文件进行读取
* @param destinationFilePath 保存带有CRC校验值的新文件的路径
* @throws IOException 如果在读取源文件或写入新文件过程中发生I/O错误
*/
public static void attachCRC16ARC(String sourceFilePath, String destinationFilePath) throws IOException {
// 打开源文件并读取所有内容
FileInputStream fis = new FileInputStream(sourceFilePath);
byte[] data = fis.readAllBytes();
fis.close();
// 计算源文件数据的CRC16ARC校验值
int crcValue = calculateCRC16ARC(data);
// 打开目标文件写入源文件数据和CRC校验值
FileOutputStream fos = new FileOutputStream(destinationFilePath);
fos.write(data);
// 写入CRC的高字节
fos.write((crcValue & 0xFF00) >> 8);
// 写入CRC的低字节
fos.write(crcValue & 0xFF);
fos.close();
}
public static byte[] generateCRC16ARCForSend(String filePath) throws IOException {
FileInputStream fis = new FileInputStream(filePath);
byte[] data = fis.readAllBytes();
fis.close();
// 计算CRC16ARC校验值
int crcValue = calculateCRC16ARC(data);
byte[] crcBytes = new byte[2];
crcBytes[0] = (byte) ((crcValue >> 8) & 0xFF); // 高位字节
crcBytes[1] = (byte) (crcValue & 0xFF); // 低位字节
byte[] dataWithCRC = new byte[data.length + 2];
System.arraycopy(data, 0, dataWithCRC, 0, data.length);
System.arraycopy(crcBytes, 0, dataWithCRC, data.length, 2);
return dataWithCRC;
}
public static boolean verifyCRC16ARCByBytes(byte[] bytes) {
int crcValue = ((bytes[bytes.length - 2] & 0xFF) << 8) | (bytes[bytes.length - 1] & 0xFF);
byte[] crcData = new byte[]{(byte) (crcValue >> 8), (byte) crcValue};
byte[] data = Arrays.copyOf(bytes, bytes.length - crcData.length);
int calculatedCRC = calculateCRC16ARC(data);
return crcValue == calculatedCRC;
}
/**
* 读取文件时提取末尾的CRC值并进行验证
* @param filePath
* @return
* @throws IOException
*/
public static boolean verifyCRC16ARC(String filePath) throws IOException {
FileInputStream fis = new FileInputStream(filePath);
byte[] data = fis.readAllBytes();
fis.close();
// 文件附带的CRC
int fileCRC = ((data[data.length - 2] & 0xFF) << 8) | (data[data.length - 1] & 0xFF);
byte[] fileData = Arrays.copyOf(data, data.length - 2);
// 重新计算的CRC
int calculatedCRC = calculateCRC16ARC(fileData);
return fileCRC == calculatedCRC;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "D:\\Downloads\\BFD-D42401883.pdf";
String destinationFilePath = "D:\\Downloads\\BFD-D42401883-1.pdf"; // 输出的
attachCRC16ARC(filePath, destinationFilePath);
if (verifyCRC16ARC(destinationFilePath)) {
System.out.println("验证成功");
}else {
System.out.println("验证失败");
}
byte[] bytes = generateCRC16ARCForSend(filePath); // 生成附带CRC的完整文件
if (verifyCRC16ARCByBytes(bytes)) { // 验证
System.out.println("验证成功");
}else {
System.out.println("验证失败");
}
System.out.println(calculateCRC16ARC(new byte[]{1}));
}
}

View File

@ -0,0 +1,74 @@
package cn.whaifree.test;
import java.util.ArrayList;
import java.util.List;
public class ShapleyValueDemo {
static class Node {
int id;
double distance;
double strength;
Node(int id, double distance, double strength) {
this.id = id;
this.distance = distance;
this.strength = strength;
}
}
public static void main(String[] args) {
List<Node> nodes = new ArrayList<>();
// 添加三个节点的信息这里以节点的 ID距离和强度为例
nodes.add(new Node(1, 0.5, 0.8));
nodes.add(new Node(2, 0.8, 0.6));
nodes.add(new Node(3, 0.7, 0.7));
List<Double> shapleyValues = calculateShapleyValues(nodes);
System.out.println("Shapley Values:");
for (int i = 0; i < nodes.size(); i++) {
System.out.println("Node " + nodes.get(i).id + ": " + shapleyValues.get(i));
}
}
public static List<Double> calculateShapleyValues(List<Node> nodes) {
List<Double> shapleyValues = new ArrayList<>();
double[] marginalContributions = new double[nodes.size()];
// 计算每个节点的 Shapley
for (int i = 0; i < nodes.size(); i++) {
for (int j = 0; j < nodes.size(); j++) {
if (i != j) {
double valueWithI = getValue(getPlayerSubset(nodes.get(i), nodes.get(j)));
double valueWithoutI = getValue(getPlayerSubset(nodes.get(j)));
marginalContributions[i] += (valueWithI - valueWithoutI);
}
}
shapleyValues.add(marginalContributions[i] / nodes.size());
}
return shapleyValues;
}
// 模拟每个节点的贡献价值
public static double getValue(List<Node> nodes) {
// 这里可以根据实际情况编写计算价值的逻辑这里简单地假设节点的贡献价值为距离与强度的乘积之和
double value = 0.0;
for (Node node : nodes) {
value += node.distance * node.strength;
}
return value;
}
// 生成不包含给定节点的组合
public static List<Node> getPlayerSubset(Node excludedNode, Node... nodes) {
List<Node> subset = new ArrayList<>();
for (Node node : nodes) {
if (node != excludedNode) {
subset.add(node);
}
}
return subset;
}
}

View File

@ -0,0 +1,39 @@
package cn.whaifree.test;
import cn.whaifree.leetCode.Hash.LeetCode1;
import java.io.*;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/1 22:08
* @注释
*/
public class byteStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream1 = new ObjectOutputStream(out);
objectOutputStream1.writeObject(new LeetCode1());
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(out.toByteArray());
//转为对象
ObjectInputStream objectInputStream1 = new ObjectInputStream(byteArrayInputStream);
LeetCode1 o1 = (LeetCode1)objectInputStream1.readObject();
o1.test();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc.txt"));
LeetCode1 obj = new LeetCode1();
obj.test();
objectOutputStream.writeObject(obj);
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc.txt"));
LeetCode1 o = (LeetCode1) objectInputStream.readObject();
o.test();
objectOutputStream.close();
}
}

View File

@ -0,0 +1,76 @@
package cn.whaifree.test;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/1 22:15
* @注释
*/
public class cglib {
public static void main(String[] args) {
// 创建目标类的代理
TargetClassProxy proxy = new TargetClassProxy();
// 使用CGLIB创建代理对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TargetClass.class);
enhancer.setCallback(proxy);
TargetClass targetProxy = (TargetClass) enhancer.create(); // Enhancer创建子类代理
// 调用代理对象的方法
targetProxy.doSomething();
System.out.println("===================");
targetProxy.doA();
}
}
class TargetClass extends TargetA{
public void doSomething() {
System.out.println("TargetClass: doSomething()");
}
}
class TargetA{
/**
* 加了final后Enhancer不会增强
* <h4>
* Before method: doSomething <br>
* TargetClass: doSomething()<br>
* After method: doSomething<br>
* ===================<br>
* TargetA: doA()<br>
* </h4>
*
* 不加final
* <h4>
* Before method: doSomething<br>
* TargetClass: doSomething()<br>
* After method: doSomething<br>
* ===================<br>
* Before method: doA<br>
* TargetA: doA()<br>
* After method: doA<br>
* </h4>
*/
public void doA(){
System.out.println("TargetA: doA()");
}
}
class TargetClassProxy implements MethodInterceptor {
@Override
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args); // 调用目标类的原始方法
System.out.println("After method: " + method.getName());
return result;
}
}

View File

@ -0,0 +1,43 @@
package cn.whaifree.test;
/**
* @version 1.0
* @Author whai文海
* @Date 2024/4/1 20:01
* @注释
*/
public class hashDB {
static final int[] hashes = {1,4}; // 哈希函数数组
// 3个库
private static final int NUM_SHARDS = 3;
public static void main(String[] args) {
// 要分库的数据
String[] id = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
// 对每个数据计算哈希值并分配到库
for (String datum : id) {
int[] shard = getShard(datum);
System.out.println("Data: " + datum + " -> Shard: " + shard[0] + ", " + shard[1]);
}
}
// 计算数据的哈希值并分配到库
private static int[] getShard(String data) {
// 使用Java的hashCode()方法计算哈希值
int hash = data.hashCode();
// 取模运算得到库编号
int[] loc = new int[hashes.length];
for (int i = 0; i < loc.length; i++) {
loc[i] = Math.abs((hash ^ hashes[i]) % NUM_SHARDS) + 1;
}
return loc;
}
}

View File

@ -2,6 +2,10 @@ package cn.whaifree.test;
import org.junit.Test; import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
/** /**
* @version 1.0 * @version 1.0
* @Author whai文海 * @Author whai文海
@ -28,3 +32,35 @@ public class testTry {
} }
} }
class SymmetricEncryptionUtil {
private static final String ALGORITHM = "AES";
private static byte[] SECRET_KEY = null; // 替换为你自己的密钥密钥长度必须符合算法要求
public static byte[] encrypt(byte[] data) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY, ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(data);
}
public static byte[] decrypt(byte[] encryptedData) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY, ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(encryptedData);
}
public static void main(String[] args) throws Exception {
SECRET_KEY = KeyGenerator.getInstance(ALGORITHM).generateKey().getEncoded();
System.out.println(new String(SECRET_KEY));
byte[] encrypt = SymmetricEncryptionUtil.encrypt("123456".getBytes());
System.out.println(new String(encrypt));
byte[] decrypt = SymmetricEncryptionUtil.decrypt(encrypt);
System.out.println(new String(decrypt));
}
}