随机取数

题目描述

现给定一个含有n个元素的数组,请随机获取其中的m个元素(不能重复获取)。

算法描述

首先,随机获取元素,可以使用rand() % 数组长度

其次,要保证元素的不重复获取,只需将获取的元素从原数组中移除即可,但是每次都进行删除操作,需要频繁的移动数组元素,其复杂度很高;现在,我们换一种思路,将获取的元素与原数组最后的元素进行交换,再将数组的长度减一,那么就可以做到O(1)复杂度将其移除;详见下图:

 

 

 

 

 

此算法的时间复杂度为O(n),其只与要获取的m个数有关,在n和m相差非常悬殊的时候,效率非常高。

程序源码

 

 

//
//  main.m
//  RandSelect
////  Copyright (c) 2013年 tencent. All rights reserved.
//

#import <Foundation/Foundation.h>
#define  MAXNUMBER 200
#define  MAXARRAYCOUNT 10

/*
 从一个随机数组中挑选一个数,不能有重复
 1. 随机生成一个数组 3,33,675,7657,2345,5767,34564,3453
 2. 挑选完了一个数则将其调换到最后去,或将其删除,如果不允许修改原始数组,则调换到最后去
 3. 输出数组
 */

void print(int *array ,int count)
{
    for (int i=0; i<count; i++) {
        printf("%d ",array[i]);
    }
    printf("\n");
}

void swap(int array[],int length,int index)
{
    int temp=array[index];
    array[index]=array[length-1];
    array[length-1]=temp; 
}


//下面假设不允许修改原始数组,输出已经挑选好了的数组
int *selectFromArray(int *array,int count)
{
    int *resultAry=new int[count];
    //如果需要不动原数组则需要复制一份
    for (int i=0; i<count; i++) {
        resultAry[i]=array[i];
//         printf("%d  ",resultAry[i]);
    }     
    //开始算法
    for (int i=0; i<count; i++) {
        int remainLength=MAXARRAYCOUNT-i;
        int tempIndx=rand()%remainLength;
        swap(resultAry,remainLength,tempIndx);
    } 
    return resultAry;
}



int main(int argc, const char * argv[])
{

    @autoreleasepool {        
        // insert code here... 
        int *array=new int(MAXARRAYCOUNT);
        for (int i=0; i<MAXARRAYCOUNT; i++) {
            array[i]=rand()%MAXNUMBER;
        }
        print(array,MAXARRAYCOUNT);        
        int *arrayb=selectFromArray(array, MAXARRAYCOUNT);
        print(arrayb, MAXARRAYCOUNT);
        
        
    }
    return 0;
}

 

posted @ 2013-12-04 16:33  Nonato  阅读(1216)  评论(2编辑  收藏  举报