Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 两个排序数组的中值:终止条件失败_Java_Arrays_Algorithm_Sorting_Median - Fatal编程技术网

Java 两个排序数组的中值:终止条件失败

Java 两个排序数组的中值:终止条件失败,java,arrays,algorithm,sorting,median,Java,Arrays,Algorithm,Sorting,Median,下面的代码是我按照 您甚至可以在 它不适用于输入数组,例如 int[] array1 = {1, 5, 17, 20}; // median is 10 int[] array2 = {4, 8, 13, 19}; int[] array1 = {1, 3, 5, 7, 9, 11}; // median is 6 int[] array2 = {2, 4, 6, 8, 10, 12}; 根据我的分析,问题是,终止条件。一些人认为Geeksforgeks提出的逻辑建议似乎与终止条件有关 (M

下面的代码是我按照

您甚至可以在

它不适用于输入数组,例如

int[] array1 = {1, 5, 17, 20}; // median is 10
int[] array2 = {4, 8, 13, 19};

int[] array1 = {1, 3, 5, 7, 9, 11}; // median is 6
int[] array2 = {2, 4, 6, 8, 10, 12};
根据我的分析,问题是,终止条件。一些人认为Geeksforgeks提出的逻辑建议似乎与终止条件有关

(Math.max(array1[low1], array2[low2]) + Math.min(array1[high1], array2[high2]))/2;
但我无法解决它,也无法使它为上述输入工作。
有人能调查一下这个问题,让我知道我犯了什么错误吗?

你的主要错误是,当你做纯
intmid1=(low1+high1)/2
您的
mid1
总是向左移动,然后您分配
mid1
而不考虑此移动,因此每个嵌套比较比较从预定位置向左移动的数组元素,并且由于长度
2n
的数组的中位数总是
a[n-1]+a[n]/2
,在第一次执行比较后,正在比较错误的数组元素。您似乎错误地实现了方法2的代码块:

    if (n % 2 == 0)
        return getMedian(ar1 + n/2 - 1, ar2, n - n/2 +1);
    else
        return getMedian(ar1 + n/2, ar2, n - n/2);
事实上,在
findMedian()
入口的简单
assert(high2-low2==high1-low1)
会提醒您错误的逻辑,因为对于大小为4的数组,第二个入口产生的数组大小不等。退出条件非常好,因为它直接从方法2的代码复制而来。因此,您需要将分配
low1\t
和其他的块更改为以下内容:

    assert (high2-low2==high1-low1); // sanity check
    int n=high1-low1+1; // "n" from logic

    int m1 = median(array1,low1,high1);
    int m2 = median(array2,low2,high2);

    int low1_t = low1;
    int high1_t = high1;
    int low2_t = low2;
    int high2_t = high2;

    if(m1 == m2) {
        return m1;
    } else if(m1 > m2) {
        if (n % 2 == 0) {
            high1_t = high1-n/2+1;
            low2_t = low2+n/2-1;
        } else {
            high1_t = high1-n/2;
            low2_t = low2+n/2;
        }
    } else {
        if (n % 2 == 0) {
            low1_t = low1+n/2-1;
            high2_t = high2-n/2+1;
        } else {
            low1_t = low1+n/2;
            high2_t = high2-n/2;
        }
    }
    return findMedian(array1, array2, low1_t, high1_t, low2_t, high2_t);
然后像这样添加函数
median

static int median(int[] arr, int low,int hig) 
{
    if ((low+hig)%2 == 0) return arr[(low+hig)/2];
    int mid=(low+hig)/2;
    return (arr[mid]+ arr[mid-1])/2;
}

完整示例(根据需要更改数组):

这是一个有效的代码,应该可以解决您的问题:-

public static void main(String[] args)
 {
    int[] ar1 = {1, 3, 5, 7, 9, 11};
    int[] ar2 = {2, 4, 6, 8, 10, 12};
  System.out.println((int) findMedianSortedArrays(ar1,ar2));
 }

 public static double findMedianSortedArrays(int A[], int B[]) {
  int m = A.length;
  int n = B.length;

  if ((m + n) % 2 != 0) // odd
   return (double) findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1);
  else { // even
   return (findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1) 
    + findKth(A, B, (m + n) / 2 - 1, 0, m - 1, 0, n - 1)) * 0.5;
  }
 }

 public static int findKth(int A[], int B[], int k, 
  int aStart, int aEnd, int bStart, int bEnd) {

  int aLen = aEnd - aStart + 1;
  int bLen = bEnd - bStart + 1;

  // Handle special cases
  if (aLen == 0)
   return B[bStart + k];
  if (bLen == 0)
   return A[aStart + k];
  if (k == 0)
   return A[aStart] < B[bStart] ? A[aStart] : B[bStart];

  int aMid = aLen * k / (aLen + bLen); // a's middle count
  int bMid = k - aMid - 1; // b's middle count

  // make aMid and bMid to be array index
  aMid = aMid + aStart;
  bMid = bMid + bStart;

  if (A[aMid] > B[bMid]) {
   k = k - (bMid - bStart + 1);
   aEnd = aMid;
   bStart = bMid + 1;
  } else {
   k = k - (aMid - aStart + 1);
   bEnd = bMid;
   aStart = aMid + 1;
  }

  return findKth(A, B, k, aStart, aEnd, bStart, bEnd);
 }
publicstaticvoidmain(字符串[]args)
{
int[]ar1={1,3,5,7,9,11};
int[]ar2={2,4,6,8,10,12};
System.out.println((int)findmediansortedarray(ar1,ar2));
}
公共静态双FindMediaTransortedArray(int A[],int B[]){
int m=A.长度;
int n=B.长度;
如果((m+n)%2!=0)//奇数
返回(双)findKth(A,B,(m+n)/2,0,m-1,0,n-1);
否则{//偶数
返回(findKth(A,B,(m+n)/2,0,m-1,0,n-1)
+findKth(A,B,(m+n)/2-1,0,m-1,0,n-1))*0.5;
}
}
公共静态int findKth(int A[],int B[],int k,
int aStart、int aEnd、int bStart、int bEnd){
int aLen=aEnd-aStart+1;
int bLen=弯曲-开始+1;
//处理特殊情况
如果(aLen==0)
返回B[B开始+k];
如果(bLen==0)
返回一个[aStart+k];
如果(k==0)
返回A[aStart]B[bMid]){
k=k-(体重指数-b开始+1);
aEnd=中间;
b开始=体重指数+1;
}否则{
k=k-(中间-aStart+1);
bEnd=bMid;
aStart=aMid+1;
}
返回findKth(A、B、k、aStart、aEnd、bStart、bEnd);
}

我说您不想合并和排序阵列(出于优化原因)对吗?否则会让你的生活easier@cahen是 啊正如您所说,合并和排序将很容易。我也写过这段代码。但这是一种不同的解决问题的方法,以获得更好的时间复杂性。你知道这不起作用的原因吗?你可以在声明时将
low1
分配给
low1\t
等,以避免所有这些分配;)@霍尔特事实上,这些零没有被使用。我只是需要代码来工作,清理应该只在之后进行。+1。。当我阅读Geeksforgeks代码时,甚至我也认为我在处理奇偶长度案例时没有正确实现。如果我遇到任何问题,我会检查并告诉你。谢谢你的代码。但我在寻找代码中的问题,而不是新代码。如果我的代码没有修复,那么我将研究您的解决方案。
public static void main(String[] args)
 {
    int[] ar1 = {1, 3, 5, 7, 9, 11};
    int[] ar2 = {2, 4, 6, 8, 10, 12};
  System.out.println((int) findMedianSortedArrays(ar1,ar2));
 }

 public static double findMedianSortedArrays(int A[], int B[]) {
  int m = A.length;
  int n = B.length;

  if ((m + n) % 2 != 0) // odd
   return (double) findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1);
  else { // even
   return (findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1) 
    + findKth(A, B, (m + n) / 2 - 1, 0, m - 1, 0, n - 1)) * 0.5;
  }
 }

 public static int findKth(int A[], int B[], int k, 
  int aStart, int aEnd, int bStart, int bEnd) {

  int aLen = aEnd - aStart + 1;
  int bLen = bEnd - bStart + 1;

  // Handle special cases
  if (aLen == 0)
   return B[bStart + k];
  if (bLen == 0)
   return A[aStart + k];
  if (k == 0)
   return A[aStart] < B[bStart] ? A[aStart] : B[bStart];

  int aMid = aLen * k / (aLen + bLen); // a's middle count
  int bMid = k - aMid - 1; // b's middle count

  // make aMid and bMid to be array index
  aMid = aMid + aStart;
  bMid = bMid + bStart;

  if (A[aMid] > B[bMid]) {
   k = k - (bMid - bStart + 1);
   aEnd = aMid;
   bStart = bMid + 1;
  } else {
   k = k - (aMid - aStart + 1);
   bEnd = bMid;
   aStart = aMid + 1;
  }

  return findKth(A, B, k, aStart, aEnd, bStart, bEnd);
 }