编程珠玑之第一章习题4: 生成不同的随机顺序的随机整数及存储与读取

2013-09-15 10:56 初版
2014-12-31 11:06 修改了程序中存在的一些bug。

这里对“生成小于n且没有重复的k个整数的问题”做一记录,以后扩充!
如下:
1.C++版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/***********************************************************/
  // 程序名称:nRandomNum.cpp
  // 程序目的:生成0至n-1之间k个不同的随机顺序的随机整数
  // 程序来源:编程珠玑源码(bitsortgen.c -- gen $1 distinct
  //           integers from U[0,$2))
  // 日期:2013-9-15 9:02:42       JohnnyHu 修改
  //            2014-12-31 10:13:06  JohnnyHu 修改
  // 作者:    Jon Bentley
/***********************************************************/

#include <iostream>
#include <cstdlib>       /* srand, rand */
#include <ctime>         /* time */
#include <algorithm>     /* std::swap*/
#include <stdexcept>     /*std::domain_error*/

using  namespace std;
const  int N =  80;
const  int K =  70;

/************************************************************************/
// 函数名称:bigrand
// 函数目的:生成范围在[0, 0x3FFFFFFF]之间的随机整数
// 使用条件:RAND_MAX = 32767(0x7FFF)
/************************************************************************/

int bigrand()
{
     return  RAND_MAX*rand() +  rand() + rand();
}

/************************************************************************/
// 函数名称:randint
// 函数目的:生成范围在[a, b]之间的随机整数
// 使用条件:RAND_MAX = 32767(0x7FFF); b >= a;
/************************************************************************/

int randint( int a,  int b)
{
     if (b < a){
        throw domain_error( "Argument to randint is out of range!");
    }
     return a +  bigrand() % (b - a  +  1);
}

/************************************************************************/
// 函数名称:set_randarray
// 函数目的:生成0至arrSize之间num个不同的随机顺序的随机整数
// 参数说明:参数1——数组,参数2——数组大小,参数3——范围(<=arrSize)
/************************************************************************/

void set_randarray( int arr[],  const  int arrSize,  const  int num)
{
     if (arrSize <  1 || num <  0 || num > arrSize){
        throw domain_error( "Argument to SetArrAand is out of range!");
    }

    srand(( unsigned) time( NULL));

     forint i =  0; i < arrSize; i++ ){
        arr[i] = i;
    }

     forint i =  0; i < num; i++ ){
        swap( arr[i], arr[randint(i, arrSize- 1)] );    // 交换数组中的两个元素
    }

     return;
}

int main()
{
     int a[N];
    set_randarray(a, N, K);
     forint i =  0; i < K; i++ ){
        cout << a[i] <<  "\t";
    }

     return  0;
}

2、C语言版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>
#include <stdlib.h>      /* srand, rand */
#include <time.h>        /* time */
#include <assert.h>      /* assert */

const  int N =  100;
const  int K =  100;


/************************************************************************/
// 函数名称:bigrand
// 函数目的:生成范围在[0, 0x3FFFFFFF]之间的随机整数
// 使用条件:RAND_MAX = 32767(0x7FFF)
/************************************************************************/

int bigrand()
{
     return  RAND_MAX*rand() +  rand() + rand();
}

/************************************************************************/
// 函数名称:randint
// 函数目的:生成范围在[a, b]之间的随机整数
// 使用条件:RAND_MAX = 32767(0x7FFF); b >= a;
/************************************************************************/

int randint( int a,  int b)
{
    assert( a <= b);
     return a +  bigrand() % (b - a  +  1);
}

/************************************************************************/
// 函数名称:set_randarray
// 函数目的:生成0至arrSize之间num个不同的随机顺序的随机整数
// 参数说明:参数1——数组,参数2——数组大小,参数3——范围(<=arrSize)
/************************************************************************/

void set_randarray( int arr[],  const  int arrSize,  const  int num)
{
    assert(arrSize >  0 && num >  0 && arrSize >= num);

    srand(( unsigned) time( NULL));

     forint i =  0; i < arrSize; i++ ){
        arr[i] = i;
    }

     int index, tmp;
     forint i =  0; i < num; i++ ){
        index = randint(i, arrSize- 1);

         // 交换数组中的两个元素
        tmp = arr[i]; arr[i] = arr[index]; arr[index] = tmp;
    }

     return;
}


int main()
{
     int a[N];
    set_randarray(a, N, K);
     forint i =  0; i < K; i++ ){
        printf( "%d\t", a[i]);
    }

    getchar();
     return  0;
}

输出结果:



3.以字符文本形式存储100w整数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <stdio.h>
#include <stdlib.h>         /* srand, rand */
#include <time.h>       /* time, clock_t*/
#include <assert.h>      /* assert */
#include <string.h>         /* memset*/

#define error( str )         fatal_error( str )
#define fatal_error( str )   fprintf( stderr,  "%s\n", str ), exit(  1 )


/************************************************************************/
// 函数名称:bigrand
// 函数目的:生成范围在[0, 0x3FFFFFFF]之间的随机整数
// 使用条件:RAND_MAX = 32767(0x7FFF)
/************************************************************************/

int bigrand()
{
     return  RAND_MAX*rand() +  rand() + rand();
}

/************************************************************************/
// 函数名称:randint
// 函数目的:生成范围在[a, b]之间的随机整数
// 使用条件:RAND_MAX = 32767(0x7FFF); b >= a;
/************************************************************************/

int randint( int a,  int b)
{
    assert( a <= b);
     return a +  bigrand() % (b - a  +  1);
}

/************************************************************************/
// 函数名称:set_randarray
// 函数目的:生成0至arrSize之间num个不同的随机顺序的随机整数
// 参数说明:参数1——数组,参数2——数组大小,参数3——范围(<=arrSize)
/************************************************************************/

void set_randarray( int arr[],  const  int arrSize,  const  int num)
{
    assert(arrSize >  0 && num >  0 && arrSize >= num);

    srand(( unsigned) time( NULL));

     forint i =  0; i < arrSize; i++ ){
        arr[i] = i;
    }

     int index, tmp;
     forint i =  0; i < num; i++ ){
        index = randint(i, arrSize- 1);

         // 交换数组中的两个元素
        tmp = arr[i]; arr[i] = arr[index]; arr[index] = tmp;
    }

     return;
}

int main()
{
     const  int N =  20;
     const  int K =  20;

     int a[N];
    set_randarray(a, N, K);

    FILE* iofile = fopen( "unsortfile.txt""w");
     if ( NULL ==  iofile){ fatal_error( "不能打开unsortfile.txt文件!\n"); }

     // 把数组中的k(个)数据写入到文件中
     forint i =  0; i < K; i++ ){ fprintf(iofile,  "%d\t", a[i]); }
    fclose(iofile);

    memset(a,  0sizeof(a));            // 数组a清零

    clock_t start_time = clock();       // 开始时间

    FILE* iofile2 = fopen( "unsortfile.txt""r");
     if ( NULL ==  iofile2){ fatal_error( "不能打开unsortfile.txt文件!\n"); }

     // 从文件中读取数据
     int index =  0;
     while(fscanf(iofile,  "%d", &a[index]) != EOF){ index++; }
    fclose(iofile2);

    clock_t end_time = clock();         // 结束时间

     float cost_time = ( float)(end_time - start_time) / CLOCKS_PER_SEC;
    printf( "文件中的记录数:%d\n", index);
    printf( "读文件耗时:%5.3f秒\n", cost_time);

     return  0;
}

输出结果如下:


4. 以二进制形式存储:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
int main()
{
     const  int N =  10000;
     const  int K =  10000;

     int a[N];
    set_randarray(a, N, K);

    FILE* iofile = iofile = fopen( "b_unsortfile.txt""wb");
     if ( NULL ==  iofile){ fatal_error( "不能打开b_unsortfile.txt文件!\n"); }

     // 把数组中的数据以二进制写入到文件中
    fwrite(a,  sizeof( int),  sizeof(a)/ sizeof( int), iofile);
    fclose(iofile);

    memset(a,  0sizeof(a));            // 数组a清零

    clock_t start_time = clock();       // 开始时间

    FILE* iofile2 = fopen( "b_unsortfile.txt""rb");
     if ( NULL ==  iofile2){ fatal_error( "不能打开b_unsortfile.txt文件!\n"); }

     // 从二进制文件中读取数据
     int index =  0;
     while(fread(&a[index],  sizeof( int),  1, iofile2) !=  0){
         if (!feof(iofile2)){ index++; }
    }
    fclose(iofile2);

    clock_t end_time = clock();         // 结束时间

     float cost_time = ( float)(end_time - start_time) / CLOCKS_PER_SEC;
    printf( "文件中的记录数:%d\n", index);
    printf( "读文件耗时:%5.3f秒\n", cost_time);

     return  0;
 }

输出结果:


注:本以为以二进制形式存储的100w文本文件所占存储空间会小一点,没想到更大,达到38M多,相反字符串存储的文本却只有8M左右大小,从读文件来看,二进制的读文件耗时也较长,不知道我有没算错!!!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值