package kpp.base;
/**
* 求两个有序数组的中位数
* 此代码适用于两个数组长度不等的情况:长度不等的情况下,两个数组分别从相反方向去掉元素,且去掉的元素个数相同
* @author kpp
*
*/
public class TwoArrayMedian {
public static void main(String[] args) {
// TODO Auto-generated method stub
float a[] = {1,2,3,4};
//float b[] = {2,3,4,5,8,9,10};
float b[] = {8,9,10,11};
System.out.println("中位数"+getTwoArrayMedian(a,b));
}
/**
* 获取两个有序数组的中位数
* @param a
* @param b
* @return
*/
private static float getTwoArrayMedian(float a[],float b[]){
int aLen = a.length;
int bLen = b.length;
//判断哪个数组长度短
float shorterArray[] = aLen <= bLen? a:b;
float longerArray[] = aLen > bLen? a:b;
//以长度短的数组shorterArray为基准,shorterArray去掉几个元素,longerArray同时在反方向去掉相同个数元素
while(shorterArray.length > 1 && longerArray.length > 1){
//如果短数组的中位数>长数组的中位数,则两个数组的中位数是在短数组的前半部分和长数组的后半部分
//留下短数组的0至n/2元素,去掉其他元素
//长数组去掉相同个数元素
if(getArrayMedian(shorterArray) > getArrayMedian(longerArray)){
float temp1[] = new float[shorterArray.length/2+1];
System.arraycopy(shorterArray, 0, temp1, 0, shorterArray.length/2+1);
int delCount = shorterArray.length-shorterArray.length/2-1;
float temp2[] = new float[longerArray.length-delCount];
System.arraycopy(longerArray, delCount-1, temp2, 0,longerArray.length-delCount);
shorterArray = temp1;
longerArray = temp2;
}
//如果短数组的中位数<长数组的中位数,则两个数组的中位数是在短数组的后半部分和长数组的前半部分
//留下短数组的n/2至n-1元素,去掉其他元素
//长数组去掉相同个数元素
else if(getArrayMedian(shorterArray) < getArrayMedian(longerArray)){
float temp1[] = new float[shorterArray.length-shorterArray.length/2];
System.arraycopy(shorterArray, shorterArray.length/2, temp1, 0, shorterArray.length-shorterArray.length/2);
int delCount = shorterArray.length/2;
float temp2[] = new float[longerArray.length-delCount];
System.arraycopy(longerArray, 0, temp2, 0,longerArray.length-delCount);
shorterArray = temp1;
longerArray = temp2;
}
//如果短数组的中位数=长数组的中位数,则两个数组的中位数就是该中位数
else{
return getArrayMedian(shorterArray);
}
}
//如果长度短的数组中只剩余一个元素,而长度长的数组还有多个元素,则将该元素插入到长数组中进行插入排序
//中位数为排好序后的数组的中位数
if(longerArray.length > 1){
float key = shorterArray[0];
float rsArray[] = new float[longerArray.length+1];
System.arraycopy(longerArray, 0, rsArray, 0,longerArray.length);
rsArray[rsArray.length-1] = key;
if(key < rsArray[rsArray.length-2]){
float temp = key;
int j = 0;
for( j = rsArray.length-2;j >=0&&temp < rsArray[j];j--);
//统一向右移动
for(int k = rsArray.length-2;k >= j+1;k--){
rsArray[k+1]=rsArray[k];
}
//插入正确位置
rsArray[j+1] = temp;
}
for(int i = 0;i < rsArray.length;i++){
System.out.print(rsArray[i]+" ");
}
return getArrayMedian(rsArray);
}
//如果两个数组各剩1个元素,则取二者平均
else{
return (shorterArray[0]+longerArray[0])/2;
}
}
/**
* 求一个数组的中位数
* @param data
* @return
*/
private static float getArrayMedian(float data[]){
int len = data.length;
int mid = len/2;
if(len%2 == 0){
return (data[mid]+data[mid-1])/2;
}else{
return data[mid];
}
}
}