【刘汝佳书】例题5-1 UVA10474 (sort与lower_bound的练习)

【2019.4.3】
1、题中没有给明数组N的大小,刘汝佳书上开了10000大小的数组,觉得这样不是很保险,所以用了malloc来开数组

2、本来想用vector,但是这样的话就不知道lower_bound该怎么用了

3、关于刘汝佳书本题代码下标越界的问题
假设数组a有n个元素,那么排序应该用sort(a, a+n),查找下标应该用lower_bound(a, a+n, x) - a
然而,我在代码里写了lower_bound(a, a+n-1, x) - a也能过,仔细想一想,如果x是要查找的前n-1个元素,这肯定能过;如果x是要查找的第n个元素(或者x是比第n个元素还大的数字),那么在(a, a+n-1)区间中找,一定会返回n-1,然后下面再根据if(a[n-1]==x)来判断,也是可以过的

可以看到,用lower_bound(a, a+n-1, x) - a,返回的最大值为n-1,AC
那么,用lower_bound(a, a+n, x) - a,返回的最大值就是n,此时下标越界,但还是可以AC

就好比下面的测例:数字为1、2、3、4,查找5,返回了下标4,由于下标越界,a[4]=1037765370,大概率不等于5,因此输出not found
虽然越界,但代码还是可以AC
在这里插入图片描述
但这样毕竟是不保险的,乱用指针非常危险,所以有两种方法:
① 我们采用lower_bound(a, a+n-1, x) - a的写法,就不会越界了
②由于输入的数字都小于10000,所以我们可以把数组开成n+1个元素大小,在最后一位放一个大于10000的数字,这样的话就不会下标越界了

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
    //freopen("C:\\Users\\Summer\\Desktop\\input.txt", "r", stdin);
    //freopen("C:\\Users\\Summer\\Desktop\\output.txt", "w", stdout);

    int numCase = 0;
    int n, q;
    while(cin>>n>>q && !(n==0&&q==0)) {
    	//开n+1个元素的数组
        int* marble = (int*)malloc((n+1)*sizeof(marble));

        for(int i = 0; i < n; i++) cin>>marble[i];
        marble[n] = 20000;		//在最后一个位置放上20000
        sort(marble, marble+n);

        printf("CASE# %d:\n", ++numCase);
        int x;
        for(int i = 0; i < q; i++) {
            cin>>x;
            int j = lower_bound(marble, marble+n, x) - marble;
            //cout<<j<<endl;
            //cout<<marble[j]<<endl;
            if(marble[j] == x)
                printf("%d found at %d\n", x, j+1);
            else
                printf("%d not found\n", x);
        }

        free(marble);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41727666/article/details/88987423