您的位置:首页 > 其它

有两等长数组A,B,所含元素相同,但顺序不同,只能取得A数组某值和B数组某值进行比较,比较结果为大于,小于,等于,但是不能取得同一数组A或者B中两个数进行比较,也不能取得某数组中的某个值

2014-12-26 15:46 537 查看
有两个数组a和b,两个数组的元素相同,但是顺序不同,写一个算法求出数组a和数组b中元素之间的对应关系。题意要求不能对同一个数组中的两个元素进行比较,也不能去取数组元素中的特定值进行比较。只能进行a和b元素之间的比较。

《程序员面试宝典》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中未确定的数来比较,不必进行二分法。

可以稍稍优化一点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐