利用二分查找找出两个数组内相等元素

语法应该没有问题,不知道为何无法打印目标值,请就我的代码修改并解释

输入格式

第一行两个整数 n,m,表示有 n 个人获得科技创新奖,m 个人获得特殊贡献奖。

第二行 n 个正整数,表示获得科技创新奖的人的编号。

第三行 m 个正整数,表示获得特殊贡献奖的人的编号。
输出格式

输出一行,为获得两个奖项的人的编号,按在科技创新奖获奖名单中的先后次序输出。


#include <stdio.h>

void bubbleSort(unsigned arr[], int len);
void Swap(unsigned int *num1, unsigned int *num2);

int main()
{
    unsigned int n,m,item=0;
    scanf("%d %d" , &n,&m);
    // n个人获得科技创新奖,m个人获得特殊贡献奖。
    
    unsigned int n_a[n] , m_a[m] , res[1];
    //存储编号 
    
    for ( int i=0 ; i<n ; i++ )
    {
        scanf("%d" , &n_a[i]);
    }
    for ( int j=0 ; j<m ; j++ )
    {
        scanf("%d" , &m_a[j]);
    }
    
    bubbleSort( n_a , n );
    bubbleSort( m_a , m );
    
    /*    for (int a=0 ; a<n ; a++ )
        {
            printf("%u\n" , n_a[a]);
        }
        
        for (int b=0 ; b<m ; b++ )
        {
            printf("%d\n" , m_a[b]);
        }*/
        
    int low=0 , high=m-1 , mid=(low + high) / 2 ;
    
    for ( int l=0 ; l<n ; l++ )
    {
        item = n_a[l];
        while ( low < high )
        {
            if ( m_a[mid] > item )
            {
                high = mid - 1;
                mid = (high + low) / 2;        
            }
            else if ( m_a[mid] < item )
            {
                low = mid + 1;
                mid = (high + low) / 2;    
            }    
            else
            {
                printf("%u" , item);
                break;                
            }    
        }        
    }
    
    return 0;
    
}
void bubbleSort(unsigned arr[], int len)
{
    for (int i = 0; i < len - 1; ++i)
    {
        for (int j = i + 1; j <= len  - 1; ++j)
        {
            if (arr[i] < arr[j])
            {
                Swap(&arr[i], &arr[j]);
            }
        }
    }
}

void Swap(unsigned int *num1,unsigned int *num2)
{
    int temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}

问题有几个:
1.题目要求按在科技创新奖获奖名单中的先后次序输出,所以n_a不需要排序
2.你的排序是从大到小排序,所以二分法遍历的时候,if和else if的操作需要换一下。
3.int low=0 , high=m-1 , mid=(low + high) / 2 ;是逗号表达式,计算顺序是从右到左,会先计算mid,但是这时候low和high还没有声明,所以需要分开写。另外,每次查找,都需要重新从0-m开始,所以需要放在for循环中。
4.while(low <=high)需要包括=的情况。
5.printf("%u" , item);这里,%u后面建议加一个空格,这个你自己定。下面的截图中没有加。
代码修改如下,如有帮助,请帮忙采纳一下,谢谢。

img

#include <stdlib.h>
#include <stdio.h>
void bubbleSort(unsigned arr[], int len);
void Swap(unsigned int *num1, unsigned int *num2);
int main()
{
    unsigned int n,m,item=0;
    scanf("%d %d" , &n,&m);
    // n个人获得科技创新奖,m个人获得特殊贡献奖。
    unsigned int *n_a ,*m_a, res[1];  //不能使用变量声明数组大小
    n_a = (unsigned int*)malloc(sizeof(unsigned int)*n);
    m_a = (unsigned int*)malloc(sizeof(unsigned int)*m);
    //存储编号 
    for ( int i=0 ; i<n ; i++ )
    {
        scanf("%d" , &n_a[i]);
    }
    for ( int j=0 ; j<m ; j++ )
    {
        scanf("%d" , &m_a[j]);
    }
    //bubbleSort( n_a , n );  //这个不需要排序
    bubbleSort( m_a , m );
        /*for (int a=0 ; a<n ; a++ )
        {
            printf("%u\n" , n_a[a]);
        }
        for (int b=0 ; b<m ; b++ )
        {
            printf("%u\n" , m_a[b]);
        }*/
    
    for ( int l=0 ; l<n ; l++ )
    {
        item = n_a[l];
        int low=0 , high=m ; 
        int mid=(low + high) / 2 ; //mid单独一行,逗号表达式的计算顺序是从右到做,所以在上面的话是错误的
        while ( low <= high ) //这里是小于等于
        {
            if ( m_a[mid] < item )
            {
                high = mid - 1;
                mid = (high + low) / 2;        
            }
            else if ( m_a[mid] > item )
            {
                low = mid + 1;
                mid = (high + low) / 2;    
            }    
            else
            {
                printf("%u " , item);
                break;                
            }    
        }        
    }

    //释放空间
    free(n_a); n_a = 0;
    free(m_a); m_a = 0;
    return 0;
}
void bubbleSort(unsigned arr[], int len)
{
    for (int i = 0; i < len - 1; ++i)
    {
        for (int j = i + 1; j <= len  - 1; ++j)
        {
            if (arr[i] < arr[j])
            {
                Swap(&arr[i], &arr[j]);
            }
        }
    }
}
void Swap(unsigned int *num1,unsigned int *num2)
{
    int temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}

1、你的排序是从大到小排的,但是在二分查找里确实按照从小到大的逻辑来查找的,所以第72行修改为:if (arr[i] > arr[j]);
2、int low=0 , high=m-1 , mid=(low + high) / 2 ;
这一行应放在for循环里,因为每一次比较n_a的新的数据时,要重新从m_a数组的头部再来一遍
3、printf("%u " , item)加个空格

觉得有用的话采纳一下哈