编程珠玑(一)

      今天有点时间,打算看点编程算法相关的东西,但是又不想单单看将数据结构和算法的课本,那些课本都太枯燥,提不起兴趣来学习。今天在网上看到《编程珠玑》这本书,下下来研究一下,讲的都是算法和问题如何求解的,通过一个例子来讲解算法,这很有意思,国外的大牛讲的也很通俗易懂,计划有时间要多看看这本书。

  今天看了第一章的例子,问题的需求如下:输入:输入的是一个文件,至多包含n个正整数,每个正整数都要小于n,n很大,如果输入时有一个整数出现了两次,就会产生一个致命的错误。输出:以赠序形式输出排序之后的整数列表。

  要解决这个问题,首先要生成自己的测试数据,一开始看的时候自己生成测试数据这块还真的把我给蒙住了,但是看到源码之后才恍然大悟。原来先生成0到n的数据,然后随机的选择一些数据将他们打乱就行了,就这么简单。附带源码如下:

int randint(int a, int b)
{
    return a + (RAND_MAX * rand() + rand()) % (b + 1 - a);
}
int* randvector(int num)
{
    int i,k,t,p;
    k=num/10;               
    int *x=new int[num];
    for (i=0;i<num;i++)
    {
        x[i]=i;
    }
    for (i=0;i<k;i++)
    {
        p=randint(i,num-1);
        t=x[p];
        x[p]=x[i];
        x[i]=t;
    }
    return x;
}

intrand函数式生成a和b之间的数,randvector是将生成的结果放在一个数组中。

为了解决问题中存贮空间的不足,作者采用了位图和位向量的概念,首先建立一个n长度的数组,将数组置零,发现测试数据中有数据m出现,就将数组的m位置1,输出的时候,按照数组中1

的位置将数据所在的位置输出就可以,这样通过转换实现了排序,很巧妙。

源码中是大牛写的代码,很是节省内存,我不能用,自己重写了。

大牛代码:

#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }

自己写的完整的代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;

#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
void clr(int i) {        a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int  test(int i){ return a[i>>SHIFT] &   (1<<(i & MASK)); }


int randint(int a, int b)
{
    return a + (RAND_MAX * rand() + rand()) % (b + 1 - a);
}
int* randvector(int num)
{
    int i,k,t,p;
    k=num/10;               
    int *x=new int[num];
    for (i=0;i<num;i++)
    {
        x[i]=i;
    }
    for (i=0;i<k;i++)
    {
        p=randint(i,num-1);
        t=x[p];
        x[p]=x[i];
        x[i]=t;
    }
    return x;
}

void Set(int a[],int k)
{
    a[k]=1;
}
int Test(int a[],int k)
{
    if (a[k])
    {
        return k;
    }
}
void main()
{
    srand((unsigned) time(NULL));
    int num=2000;
    int *x=randvector(num);
    for (int i=0;i<num;i++)
    {
        cout<<x[i]<<endl;
    }
    cout<<"--------------------"<<endl;
//     vector<int> intv;
//     for (i=0;i<num;i++)
//     {
//         intv.push_back(x[i]);
//     }
//     sort(intv.begin(),intv.end());
//     for (vector<int>::iterator iter=intv.begin();iter!=intv.end();iter++)
//     {
//         cout<<*iter<<endl;
//     }
    int *flag=new int[num];
    memset(flag,0,sizeof(int)*num);
    for (int j=0;j<num;j++)
    {
        Set(flag,x[j]);
    }
    for (int k=0;k<num;k++)
    {
        cout<<Test(flag,k)<<"  ";
    }
}

 

 

 

posted @ 2012-10-26 20:43  lscheng  阅读(447)  评论(0编辑  收藏  举报