算法导论 9.3-8 寻找数组X[1..n],Y[1...n] 合并后的中位数
来源:互联网 发布:java面向对象编程pdf 编辑:程序博客网 时间:2024/05/21 15:47
题目:找两个已经排序的数组X[1..n],Y[1...n] 合并后的中位数,要求算法时间是logn。
稍微想了一下,利用中位数的思想来进行二分,这样就可以在logn的时间内找到中位数。按照这个思想写出来的代码在一定概率下能够找到中位数,但是有些情况发会发生常数项的偏移。后来看 “正在跟新昵称“ 童鞋的blog,发现他进行了很好地修正。 十分感谢。 附上代码:
#include <iostream>#include <cstdlib>#include <algorithm>#include <ctime>using namespace std;int * generateArray(int n);void printArray(int *A,int p,int r);void FindMiddle(int*A,int *B,int n);void vilentMiddle(int *A,int *B,int n);void FindMiddleB(int*A,int *B,int n);int main (){ srand(time(NULL)); int k = 15; int *A = generateArray(k); printArray(A,0,k); int *B = generateArray(k); printArray(B,0,k); FindMiddle(A,B,k); //FindMiddleB(A,B,k); vilentMiddle(A,B,k);}int * generateArray(int n){ int *A = new int[n]; for (int i =0;i < n;i ++) { A[i] = rand(); } sort(A,A+n); return A;}void printArray(int *A,int p,int r){ for (int i = p;i < r;i ++) { cout << A[i] <<'\t'; } cout <<endl << "--------------------------------" << endl;}void FindMiddle(int*A,int *B,int n){ int sa = 0,sb = 0; int ea = n-1, eb = n-1; int ma = 0,mb = 0; if (A[n-1] <= B[0]) { cout << A[n-1] << ' ' <<B[0] <<endl; return; } if (B[n-1] <= A[0]) { cout <<B[n-1] << ' ' << A[0] <<endl; return; } while (sa < ea && sb<eb) { ma = (ea+sa)/2; mb = (eb+sb)/2; if (A[ma] < B[mb]) { sa = ma; eb = mb; } else { ea = ma; sb = mb; } } int t = ma + mb +2; cout <<t <<endl; cout << n-t << endl; bool flag = false; if (n-t > 0)//进行修正 { for (int i = 1; i <= n-t; i ++) { ++ma; ++mb; if(A[ma] < B[mb]) { cout << "as" << A[ma] << ' '<< B[mb] << endl; --mb; flag = false; } else { cout << "ds" << A[ma] << ' '<< B[mb] << endl; --ma; flag = true; } } if (flag) { cout << B[mb] <<endl; } else { cout << A[ma] << endl; } } else { if (A[ma] < B[mb]) { cout << B[mb] <<endl; } else { cout <<A[ma] << endl; } } // cout << A[ma] << ' ' << B[mb] <<endl; /* if (true) { cout << A[sa] << ' ' << A[ea] <<endl << B[sa] << ' ' << B[ea] <<endl; } else{ cout << A[ma] <<endl; }*/}void FindMiddleB(int*A,int *B,int n){ int sa = 0,sb = 0; int ea = n-1, eb = n-1; int ma = 0,mb = 0; if (A[n-1] <= B[0]) { cout << A[n-1] << ' ' <<B[0] <<endl; return; } if (B[n-1] <= A[0]) { cout <<B[n-1] << ' ' << A[0] <<endl; return; } while (sa < ea && sb<eb) { ma = (ea+sa+1)/2; mb = (eb+sb+1)/2; if (A[ma] < B[mb]) { sa = ma; eb = mb; } else { ea = ma; sb = mb; } } int t = ma + mb +2; cout <<t <<endl; cout << n-t << endl; cout <<A[ma] << ' ' << B[mb] <<endl; bool flag = false; if (t-n-1> 0) { for (int i = 1; i <= t-n-1; i ++) { --ma; --mb; if(A[ma] < B[mb]) { cout << "as" << A[ma] << ' '<< B[mb] << endl; ++ma; flag = false; } else { cout << "ds" << A[ma] << ' '<< B[mb] << endl; ++mb; flag = true; } } if (flag) { cout << B[mb] <<endl; } else { cout << A[ma] << endl; } } else { if (A[ma] < B[mb]) { cout << B[mb] <<endl; } else { cout <<A[ma] << endl; } } // cout << A[ma] << ' ' << B[mb] <<endl; /* if (true) { cout << A[sa] << ' ' << A[ea] <<endl << B[sa] << ' ' << B[ea] <<endl; } else{ cout << A[ma] <<endl; }*/}void vilentMiddle(int *A,int *B,int n){ int *C = new int[2*n]; for (int i = 0;i < n;i ++) { C[i] = A[i]; C[i+n] = B[i]; } sort(C,C+2*n); cout << C[n-1] <<' ' <<C[n] << endl; printArray(C,0,2*n); delete []C;}
上面一段代码中,修正最终结果的那段代码虽然是可以用的,但是不知道怎么推出来的。囧。
0 0
- 算法导论 9.3-8 寻找数组X[1..n],Y[1...n] 合并后的中位数
- 算法导论9.3-8 找出已排序的2个数组X[1..n]和Y[1..n]的共2n个数的中位数
- 算法导论9.3-8-设X[1..n]和Y[1..n]为两个数组,每个都包含n个已排好序的数,给出一个求数组X和数组Y中所有2n个元素的中位数
- 找出数组X和Y中所有2n个元素的中位数
- 给定两个有序的n长度的数组,如何找出这两个数组合并后的中位数?
- X数组和Y数组的中位数
- 算法导论 9.3-7 O(n)时间求最接近中位数的k个数
- 算法导论 9.3-8 求两个数组的中位数
- 算法导论 9.3-8 求两个数组的中位数
- 算法导论 9.3-8 求两个数组的中位数
- 两个数组合并后的中位数
- 算法导论2-1.4:给出两个长度为n的二进制数(当前存放在数组中),求和后放入长度为n+1的数组中
- 求中位数的O(n)算法
- 分治法求 两个数组 X 和 Y 的中位数
- 寻找两个有序数组合并之后的中位数
- 2个有序数组,寻找他们合并之后的中位数
- 求两个等长已排序数组的中位数(算法导论习题9.3-8)
- 算法实现——X和Y的中位数问题
- 动态IP或无公网IP时在自己服务器发布网站的方法
- webservice表单传值配置接口
- Matlab plot画图的用法
- 类的加载顺序
- iOS中使用钥匙串
- 算法导论 9.3-8 寻找数组X[1..n],Y[1...n] 合并后的中位数
- 起重吊装作业时工作人员注意事项
- 最完整的htaccess文件用法收集整理
- UIWindow 介绍1:概述、作用、主要属性及方法
- OC门
- 详解Apache下.htaccess文件常用配置
- java classloader
- cadence 操作技巧
- 几个简单算法