Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit afb0888

Browse files
optimize Shell-Sort Algorithm.
1 parent 6051c87 commit afb0888

File tree

3 files changed

+162
-5
lines changed

3 files changed

+162
-5
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.example;
2+
3+
4+
import java.util.ArrayList;
5+
import java.util.Collections;
6+
7+
public class LeetcodeTest {
8+
9+
public static void main(String[] args) {
10+
// String a = "1234567891011121314151617181920";
11+
// String b = "2019181716151413121110987654321";
12+
13+
// String a = "999999999999";
14+
// String b = "999999999999";
15+
16+
String a = "24566";
17+
String b = "452053";
18+
19+
// String a = "98";
20+
// String b = "21";
21+
22+
char[] charArr1 = a.trim().toCharArray();
23+
char[] charArr2 = b.trim().toCharArray();
24+
25+
// 字符数组转换为int[]数组
26+
int[] arr1 = new int[charArr1.length];
27+
int[] arr2 = new int[charArr2.length];
28+
for(int i = 0; i < charArr1.length; i++){
29+
arr1[i] = charArr1[i] - '0';
30+
}
31+
for(int i = 0; i < charArr2.length; i++){
32+
arr2[i] = charArr2[i] - '0';
33+
}
34+
35+
// 开始计算
36+
// int[] result = LeetcodeTest.bigNumberMultiply2(arr1, arr2);
37+
// System.out.println(a + " * " + b + " = " + Arrays.toString(result).replace(", ", ""));
38+
System.out.println(LeetcodeTest.karatsuba(24566 , 452053));
39+
}
40+
41+
42+
/**
43+
* 大数相乘 - 模拟乘法手算累加
44+
*/
45+
public static Integer[] bigNumberMultiply(int[] arr1, int[] arr2){
46+
ArrayList<Integer> result = new ArrayList<>(); //中间求和的结果
47+
48+
//arr2 逐位与arr1相乘
49+
for(int i = arr2.length - 1; i >= 0; i--){
50+
int carry = 0;
51+
ArrayList<Integer> singleList = new ArrayList<>();
52+
53+
//arr2 逐位单次乘法的结果
54+
for(int j = arr1.length - 1; j >= 0; j--){
55+
int r = arr2[i] * arr1[j] + carry;
56+
int digit = r % 10;
57+
carry = r / 10;
58+
59+
singleList.add(digit);
60+
}
61+
if(carry != 0){
62+
singleList.add(carry);
63+
}
64+
65+
int resultCarry = 0, count = 0;
66+
int k = 0;
67+
int l = 0;
68+
int offset = arr2.length - 1 - i; //加法的偏移位
69+
ArrayList<Integer> middleResult = new ArrayList<>();
70+
71+
//arr2每位乘法的结果与上一轮的求和结果相加,从右向左做加法并进位
72+
while (k < singleList.size() || l < result.size()) {
73+
int kv = 0, lv = 0;
74+
if (k < singleList.size() && count >= offset) {
75+
kv = singleList.get(k++);
76+
}
77+
if (l < result.size()) {
78+
lv = result.get(l++);
79+
}
80+
int sum = resultCarry + kv + lv;
81+
middleResult.add(sum % 10); //相加结果从右向左(高位到低位)暂时存储,最后需要逆向输出
82+
resultCarry = sum / 10;
83+
count++;
84+
}
85+
if(resultCarry != 0){
86+
middleResult.add(resultCarry);
87+
}
88+
result.clear();
89+
result = middleResult;
90+
}
91+
92+
Collections.reverse(result); //逆向输出结果
93+
return result.toArray(new Integer[result.size()]);
94+
}
95+
96+
97+
/**
98+
* 大数相乘 - 模拟乘法手算累加
99+
*/
100+
public static int[] bigNumberMultiply2(int[] num1, int[] num2){
101+
// 分配一个空间,用来存储运算的结果,num1长的数 * num2长的数,结果不会超过num1+num2长
102+
int[] result = new int[num1.length + num2.length];
103+
104+
// 先不考虑进位问题,根据竖式的乘法运算,num1的第i位与num2的第j位相乘,结果应该存放在结果的第i+j位上
105+
for (int i = 0; i < num1.length; i++){
106+
for (int j = 0; j < num2.length; j++){
107+
result[i + j + 1] += num1[i] * num2[j];
108+
}
109+
}
110+
111+
//单独处理进位
112+
for(int k = result.length-1; k > 0; k--){
113+
if(result[k] > 10){
114+
result[k - 1] += result[k] / 10;
115+
result[k] %= 10;
116+
}
117+
}
118+
return result;
119+
}
120+
121+
/**
122+
* Karatsuba乘法
123+
*/
124+
public static long karatsuba(long num1, long num2){
125+
if(num1 < 10 || num2 < 10) return num1 * num2;
126+
127+
// 计算拆分长度
128+
int size1 = String.valueOf(num1).length();
129+
int size2 = String.valueOf(num2).length();
130+
int halfN = Math.max(size1, size2) / 2;
131+
132+
/* 拆分为a, b, c, d */
133+
long a = Long.valueOf(String.valueOf(num1).substring(0, size1 - halfN));
134+
long b = Long.valueOf(String.valueOf(num1).substring(size1 - halfN));
135+
long c = Long.valueOf(String.valueOf(num2).substring(0, size2 - halfN));
136+
long d = Long.valueOf(String.valueOf(num2).substring(size2 - halfN));
137+
138+
// 计算z2, z0, z1, 此处的乘法使用递归
139+
long z2 = karatsuba(a, c);
140+
long z0 = karatsuba(b, d);
141+
long z1 = karatsuba((a + b), (c + d)) - z0 - z2;
142+
143+
return (long)(z2 * Math.pow(10, (2*halfN)) + z1 * Math.pow(10, halfN) + z0);
144+
}
145+
146+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.example;
2+
3+
/**
4+
* Created by xuewenlong on 2017年8月1日.
5+
*/
6+
7+
public class ListNode {
8+
int val;
9+
ListNode next;
10+
ListNode(int x) { val = x; }
11+
}

‎src/main/java/com/example/SortAlgorithms.java‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,16 @@ public static void insertionSort(int[] arr){
8484
*/
8585
public static void shellSort(int[] arr){
8686
int gap = arr.length / 2;
87-
System_out_println("Gap=" + gap);
8887
for (; gap > 0; gap /= 2) { //不断缩小gap,直到1为止
89-
for (int j = 0; (j+gap) < arr.length; j++){ //使用每个gap进行遍历
90-
for(int k = 0; (k+gap) < arr.length; k += gap){
91-
System_out_println("k=" + k + ", k+gap: " + (k+gap));
88+
System_out_println("Gap=" + gap);
89+
for (int j = gap; j < arr.length; j++){ //使用当前gap挨个进行遍历
90+
for(int k = j-gap; k >= 0; k -= gap){ //两两一组,间隔进行比较
91+
System_out_println("Compare: k=" + k + ", k+gap=" + (k+gap));
9292
if(arr[k] > arr[k+gap]){
9393
int temp = arr[k+gap]; //交换操作
9494
arr[k+gap] = arr[k];
9595
arr[k] = temp;
96-
System_out_println("Gap=" + gap + ", Sorting: " + Arrays.toString(arr));
96+
System_out_println(" Sorting: " + Arrays.toString(arr));
9797
}
9898
}
9999
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /