最近工作需要 要求把python的代碼寫成java版本,python中有一個np.median()求中位數的方法,java決定手寫一個
先說說什么是中位數:
中位數就是中間的那個數,
如果一個集合是奇數個,那么中位數就是按大小排列后,最中間那個數,
如果一個集合是偶數個,那么中位數就是按大小排列后,最中間那2個數的平均數。
比如:
1,2,3,4,5 那中位數就是3
1,2,3,4,5,6 那中位數就是 (3+4)/2 = 3.5
知道邏輯后方法就很簡單了 下面是代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public static void main(String[] args) { List<Integer> total = new ArrayList<Integer>(); total.add(4); total.add(2); total.add(3); total.add(1); total.add(5); total.add(6); double a = median(total); System.out.println(a); } private static double median(List<Integer> total) { double j = 0; //集合排序 Collections.sort(total); int size = total.size(); if (size % 2 == 1){ j = total.get((size-1)/2); } else { //加0.0是為了把int轉成double類型,否則除以2會算錯 j = (total.get(size/2-1) + total.get(size/2) + 0.0)/2; } return j; } |
1. 方法內先判斷集合是奇數還是偶數,如果是奇數那么就是第n+1/2個數 ,也就是下標為n-1/2的值,
如果是偶數 就是第n/2和n/2+1的數的平均值 也就是下標為n/2-1和n/2的平均值
2. 該方法傳入的是list集合 如果為數組 可以先用Arrays.aslist()方法轉換后傳入
補充知識:Java計算中位數、方差、標準差、眾數
我就廢話不多說了,大家還是直接看代碼吧~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
import java.text.DecimalFormat; import java.util.*; /** * 數學算法(數學算法(方差、標準差、中位數、眾數)) * @author * */ public class MathAlgorithm { private final static double dmax = 999 ; // Double.MAX_VALUE;//Double類型的最大值,太大的double值,相乘會達到無窮大 private final static double dmin = Double.MIN_VALUE; // Double類型的最小值 private final static int n = 100 ; // 假設求取100個doubl數的方差和標準差 public static void main(String[] args) { Random random = new Random(); double [] x = new double [n]; for ( int i = 0 ; i < n; i++) { // 隨機生成n個double數 x[i] = Double.valueOf(Math.floor(random.nextDouble() * (dmax - dmin))); System.out.println(x[i]); } // 設置doubl字符串輸出格式,不以科學計數法輸出 DecimalFormat df = new DecimalFormat( "#,##0.00" ); // 格式化設置 // 計算方差 double dV = getVariance(x); System.out.println( "方差=" + df.format(dV)); // 計算標準差 double dS = getStandardDiviation(x); System.out.println( "標準差=" + df.format(dS)); int [] intArr={ 5 , 10 , 15 , 8 , 6 }; System.out.println(Arrays.toString(intArr)+ " 中位數:" +median(intArr)); int [] intArr2={ 5 , 10 , 15 , 8 , 6 , 7 }; System.out.println(Arrays.toString(intArr2)+ " 中位數:" +median(intArr2)); int [] arr = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 1 , 1 , 2 , 2 , 3 , 4 , 5 }; List<Integer> modalNums = getModalNums(arr); System.out.println( "眾數:" +modalNums); float [] arr2 = { 0 .1f, 1 .1f, 2 .1f, 3 .1f, 4 .1f, 5 .1f, 6 .1f, 7 .1f, 8 .1f, 9 .1f, 10 .1f, 1 .1f, 1 .1f, 2 .1f, 2 .1f, 3 .1f, 4 .1f, 5 .1f}; List<Float> modalNums2 = getModalNums(arr2); System.out.println( "眾數:" +modalNums2); } /** * 方差s^2=[(x1-x)^2 +...(xn-x)^2]/n * @param x * @return */ public static double getVariance( double [] x) { int m = x.length; double sum = 0 ; for ( int i = 0 ; i < m; i++) { // 求和 sum += x[i]; } double dAve = sum / m; // 求平均值 double dVar = 0 ; for ( int i = 0 ; i < m; i++) { // 求方差 dVar += (x[i] - dAve) * (x[i] - dAve); } return dVar / m; } /** * 標準差σ=sqrt(s^2) * @param x * @return */ public static double getStandardDiviation( double [] x) { int m = x.length; double sum = 0 ; for ( int i = 0 ; i < m; i++) { // 求和 sum += x[i]; } double dAve = sum / m; // 求平均值 double dVar = 0 ; for ( int i = 0 ; i < m; i++) { // 求方差 dVar += (x[i] - dAve) * (x[i] - dAve); } return Math.sqrt(dVar / m); } /** * 中位數(int) * @param nums: A list of integers. * @return: An integer denotes the middle number of the array. */ public static int median( int []nums){ if (nums.length== 0 ) return 0 ; int start= 0 ; int end=nums.length- 1 ; int index=partition(nums, start, end); if (nums.length% 2 == 0 ){ while (index!=nums.length/ 2 - 1 ){ if (index>nums.length/ 2 - 1 ){ index=partition(nums, start, index- 1 ); } else { index=partition(nums, index+ 1 , end); } } } else { while (index!=nums.length/ 2 ){ if (index>nums.length/ 2 ){ index=partition(nums, start, index- 1 ); } else { index=partition(nums, index+ 1 , end); } } } return nums[index]; } private static int partition( int nums[], int start, int end){ int left=start; int right=end; int pivot=nums[left]; while (left<right){ while (left<right&&nums[right]>=pivot){ right--; } if (left<right){ nums[left]=nums[right]; left++; } while (left<right&&nums[left]<=pivot){ left++; } if (left<right){ nums[right]=nums[left]; right--; } } nums[left]=pivot; return left; } /** * 中位數(float) * @param nums: A list of integers. * @return: An integer denotes the middle number of the array. */ public static float median( float []nums){ if (nums.length== 0 ) return 0 ; int start= 0 ; int end=nums.length- 1 ; int index=partition(nums, start, end); if (nums.length% 2 == 0 ){ while (index!=nums.length/ 2 - 1 ){ if (index>nums.length/ 2 - 1 ){ index=partition(nums, start, index- 1 ); } else { index=partition(nums, index+ 1 , end); } } } else { while (index!=nums.length/ 2 ){ if (index>nums.length/ 2 ){ index=partition(nums, start, index- 1 ); } else { index=partition(nums, index+ 1 , end); } } } return nums[index]; } private static int partition( float nums[], int start, int end){ int left=start; int right=end; float pivot=nums[left]; while (left<right){ while (left<right&&nums[right]>=pivot){ right--; } if (left<right){ nums[left]=nums[right]; left++; } while (left<right&&nums[left]<=pivot){ left++; } if (left<right){ nums[right]=nums[left]; right--; } } nums[left]=pivot; return left; } /** * 眾數(int) * 眾數:在一個數組中出現次數最多的數 * 如果存在多個眾數,則一起返回 * @param arr * @return */ public static List<Integer> getModalNums( int [] arr) { int n = arr.length; if (n == 0 ) { return new ArrayList<Integer>(); } if (n == 1 ) { return Arrays.asList(arr[ 0 ]); } Map<Integer, Integer> freqMap = new HashMap<>(); for ( int i = 0 ; i < n; i++) { // 統計數組中每個數出現的頻率 Integer v = freqMap.get(arr[i]); // v == null 說明 freqMap 中還沒有這個 arr[i] 這個鍵 freqMap.put(arr[i], v == null ? 1 : v + 1 ); } // 將 freqMap 中所有的鍵值對(鍵為數,值為數出現的頻率)放入一個 ArrayList List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(freqMap.entrySet()); // 對 entries 按出現頻率從大到小排序 Collections.sort(entries, new Comparator<Map.Entry<Integer, Integer>>() { @Override public int compare(Map.Entry<Integer, Integer> e1, Map.Entry<Integer, Integer> e2) { return e2.getValue() - e1.getValue(); } }); List<Integer> modalNums = new ArrayList<>(); modalNums.add(entries.get( 0 ).getKey()); // 排序后第一個 entry 的鍵肯定是一個眾數 int size = entries.size(); for ( int i = 1 ; i < size; i++) { // 如果之后的 entry 與第一個 entry 的 value 相等,那么這個 entry 的鍵也是眾數 if (entries.get(i).getValue().equals(entries.get( 0 ).getValue())) { modalNums.add(entries.get(i).getKey()); } else { break ; } } return modalNums; } /** * 眾數(float) * 眾數:在一個數組中出現次數最多的數 * 如果存在多個眾數,則一起返回 * @param arr * @return */ public static List<Float> getModalNums( float [] arr) { int n = arr.length; if (n == 0 ) { return new ArrayList<Float>(); } if (n == 1 ) { return Arrays.asList(arr[ 0 ]); } Map<Float, Integer> freqMap = new HashMap<>(); for ( int i = 0 ; i < n; i++) { // 統計數組中每個數出現的頻率 Integer v = freqMap.get(arr[i]); // v == null 說明 freqMap 中還沒有這個 arr[i] 這個鍵 freqMap.put(arr[i], v == null ? 1 : v + 1 ); } // 將 freqMap 中所有的鍵值對(鍵為數,值為數出現的頻率)放入一個 ArrayList List<Map.Entry<Float, Integer>> entries = new ArrayList<>(freqMap.entrySet()); // 對 entries 按出現頻率從大到小排序 Collections.sort(entries, new Comparator<Map.Entry<Float, Integer>>() { @Override public int compare(Map.Entry<Float, Integer> e1, Map.Entry<Float, Integer> e2) { return e2.getValue() - e1.getValue(); } }); List<Float> modalNums = new ArrayList<>(); modalNums.add(entries.get( 0 ).getKey()); // 排序后第一個 entry 的鍵肯定是一個眾數 int size = entries.size(); for ( int i = 1 ; i < size; i++) { // 如果之后的 entry 與第一個 entry 的 value 相等,那么這個 entry 的鍵也是眾數 if (entries.get(i).getValue().equals(entries.get( 0 ).getValue())) { modalNums.add(entries.get(i).getKey()); } else { break ; } } return modalNums; } } |
以上這篇java 計算中位數的實現方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/zhang_z_ming/article/details/85779901