有两等长数组A,B,所含元素相同,但顺序不同,只能取得A数组某值和B数组某值进行比较,比较结果为大于,小于,等于,但是不能取得同一数组A或者B中两个数进行比较,也不能取得某数组中的某个值
2014-12-26 15:46
537 查看
有两个数组a和b,两个数组的元素相同,但是顺序不同,写一个算法求出数组a和数组b中元素之间的对应关系。题意要求不能对同一个数组中的两个元素进行比较,也不能去取数组元素中的特定值进行比较。只能进行a和b元素之间的比较。
《程序员面试宝典》P93
一、O(n2)的解法
先取A0,与B0~Bn-1比较,比较结果计入一个结构数组C,结构为:{某数在B中的位置,标记,某数在A中的位置}。其中“标记”可为:大于,小于,等于。“某数在A/B中的位置”:0~n-1,为相应位置。注:第一次比较后,C中元素都为{某数在B中的位置,标记,A0}格式。
取A1,由C可知B中与A0大小相同的数,与其比较。若A2大,则与B中比A0大的值比较。将比较结果替换计入结构数组C。若A2小亦同理。
执行至完毕。
三、还可以进一步优化:
1。从A0出发。第一步同。(和B 数组中进行比较,根据你的数据结构,将B数组每个数与A[i]进行比较,若比 A[i] 大的按照从后向前存储,比 A[i] 小的从前向后存储,要是等于A[i] ,就记录下来 这个值在B的位置 j,继续比较,直到B中数组全部比较完成,然后再把这个相等的b[j] 插入空余的那个中间位置上。)
这里,j已经为一个定值。下面的m,p相同
2。考虑A1。与Bj比较。若A1大,则比较A1与Bj后的数。并更新C中Bj后的全部。计与A1相同的值为Bm。若A1小,同理。
3。考虑A2。先与Bj比较(假设上一步中A1比Bj大):
3.1若A2大,则与Bm比较。
3.1.1若A2大,更新Bm后的全部。计与A2同者为Bp。
3.1.2若A2小,更新Bj~Bm中的全部。计与A2同者为Bp。
3.2若A2小。更新Bj前的全部。
4。考虑A3。同理。
-----
在以后的步骤里,A中的数,如A[i]。与C中的数比较时,应该先与C最中间(若最中间数据尚未确定,则取最靠近)的数据比较。若A[i]属于C的后半部分,则再与后半部分的中间的数据相比。也就是尽量靠近使用二分法。
另外,当进行到一定条件下时:(Ai利用二分法来与C中的数比较,以确定Ai的位置)这个比较次数已经大于(C中所有未确定的数)的数量时,可以直接与C中未确定的数来比较,不必进行二分法。
可以稍稍优化一点。
《程序员面试宝典》P93
一、O(n2)的解法
#include <iostream> using namespace std; void matching(int a[],int b[],int k) { int i = 0; while(i <= k) { int j = 0; while(j <= k) { if(a[i] == b[j]) { cout << "(" << i <<"," << j <<") "; break; } j++; } i++; } cout << endl; } int main() { int a[10] = {1,2,3,4,5,6,7,8,9,10}; int b[10] = {10,6,4,5,1,8,7,9,3,2}; int k = sizeof(a)/sizeof(int); matching(a,b,k); return 0; }二、利用二分法优化
先取A0,与B0~Bn-1比较,比较结果计入一个结构数组C,结构为:{某数在B中的位置,标记,某数在A中的位置}。其中“标记”可为:大于,小于,等于。“某数在A/B中的位置”:0~n-1,为相应位置。注:第一次比较后,C中元素都为{某数在B中的位置,标记,A0}格式。
取A1,由C可知B中与A0大小相同的数,与其比较。若A2大,则与B中比A0大的值比较。将比较结果替换计入结构数组C。若A2小亦同理。
执行至完毕。
typedef struct { int loc_b; int flag;//-1,0,1分别表示b[loc_b]<,=,>a[loc_a] int loc_a; }C;
数组定义如下 C c ; int a ; int b ; //利用快排的思想和二分查找的思想对数组进行比较。利用a[0]初始化数组c,其中数组前半部分表示b[j]<a[0],后面部分表示b[j]>a[0].同时记录k,使得b[k]==a[0],以后对a数组进行比较时均与b[k]进行比较,(因为不让同数组之间进行比较). void _match(){ int head=0; int tail=N-1; int i,j,k; i=rand()%N; //初始化赋值 for(j=0;j<N;j++){//类似与按照a[i]的值对b进行快排 if(b[j]>a[i]){//从后向前插入到c c[tail].flag=1; c[tail].loc_a=i; c[tail].loc_b=j; tail--; continue; } if(b[j]<a[i]){//从前向后插入到c c[head].flag=-1; c[head].loc_a=i; c[head].loc_b=j; head++; continue; } if(b[j]==a[i]){ k=j;//记录相等时候的位置 } } c[head].flag=0; c[head].loc_a=i; c[head].loc_b=k; //endfor for(i=0;i<N;i++){ if(a[i]<b[k]){//a[i]小于b[k]时候,从c的前面进行比较 for(j=0;j<head;j++){ if(b[c[j].loc_b]==a[i]){ c[j].flag=0; c[j].loc_a=i; break; } } }else if(a[i]>b[k]){//从c的后面比较 for(j=head+1;j<N;j++){ if(b[c[j].loc_b]==a[i]){ c[j].flag=0; c[j].loc_a=i; break; } } } } } 进行测试 int main(){ int i=0; for(i=0;i<N;i++){ a[i]=i; b[i]=N-i-1; } _match(); for(i=0;i<N;i++){ cout<<"b["<<c[i].loc_b<<"] match a["<<c[i].loc_a<<"]"<<endl; } return 0; }
三、还可以进一步优化:
1。从A0出发。第一步同。(和B 数组中进行比较,根据你的数据结构,将B数组每个数与A[i]进行比较,若比 A[i] 大的按照从后向前存储,比 A[i] 小的从前向后存储,要是等于A[i] ,就记录下来 这个值在B的位置 j,继续比较,直到B中数组全部比较完成,然后再把这个相等的b[j] 插入空余的那个中间位置上。)
这里,j已经为一个定值。下面的m,p相同
2。考虑A1。与Bj比较。若A1大,则比较A1与Bj后的数。并更新C中Bj后的全部。计与A1相同的值为Bm。若A1小,同理。
3。考虑A2。先与Bj比较(假设上一步中A1比Bj大):
3.1若A2大,则与Bm比较。
3.1.1若A2大,更新Bm后的全部。计与A2同者为Bp。
3.1.2若A2小,更新Bj~Bm中的全部。计与A2同者为Bp。
3.2若A2小。更新Bj前的全部。
4。考虑A3。同理。
-----
在以后的步骤里,A中的数,如A[i]。与C中的数比较时,应该先与C最中间(若最中间数据尚未确定,则取最靠近)的数据比较。若A[i]属于C的后半部分,则再与后半部分的中间的数据相比。也就是尽量靠近使用二分法。
另外,当进行到一定条件下时:(Ai利用二分法来与C中的数比较,以确定Ai的位置)这个比较次数已经大于(C中所有未确定的数)的数量时,可以直接与C中未确定的数来比较,不必进行二分法。
可以稍稍优化一点。
相关文章推荐
- JAVA两个数组间元素的比较(找出相同或者不同元素)
- 编程菜鸟的日记-初学尝试编程-寻找等长数组A与B(所含元素相同,顺序不同)相匹配的元素即a[i]=b[j]
- JAVA两个数组间元素的比较(找出相同或者不同元素)
- 定义一个100长度的整型数组,使用rand函数生产随机数对每个元素进行赋值,顺序遍历该数组,输出所有值大于50的数
- 将数组中所有小于或等于0的元素都放在数组前面,大于0的元素放在数组后面
- 定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印G
- 3 定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同
- asp两个数组如何进行比较,剔除相同,保留不同
- iOS小问题--使用NSPredicate比较两个数组中相同(不同)的元素
- (***)有两个10个元素的数组,分别为A和B,编程实现相同位置的元素, 如果 B 的元素小于 A 的元素进行数值交换:(使用回调函数实现)
- 请定义一个宏,比较两个数的a、b的大小,不能使用大于、小于、if语句
- 汇编 输入几个数子进行比较 不同条输出不同的结果 三个相同输出2 两个同输出1 不同输出0
- 请定义一个宏,比较两个数的a、b的大小,不能使用大于、小于、if语句
- 3.定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同打
- 已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。 给定一个int数组A,同时给定
- 将数组中所有小于或等于0的元素都放在数组前面,大于0的元素放在数组后面
- 定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印G
- 定义一个100长度的整型数组,使用rand函数生产随机数对每个元素进行赋值,顺序遍历该数组,输出所有值大于50的数。输出格式例子为:
- 将数组中所有小于或等于0的元素都放在数组前面,大于0的元素放在数组后面。要求时间复杂度为o(n)
- 第一次发博客,新手初试啊,题目如下:有两个10个元素的数组,分别为A和B,编程实现相同位置的元素, 如果 B 的元素小于 A 的元素进行数值交换:(使用回调函数实现)