zoukankan      html  css  js  c++  java
  • 编程珠玑(一)

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

      今天看了第一章的例子,问题的需求如下:输入:输入的是一个文件,至多包含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)<<"  ";
        }
    }
  • 相关阅读:
    【HTML】Advanced7:HTML5 Forms Pt. 2: Attributes and Data Lists
    android动画效果(转载)
    Android 启动界面的实现(转载)
    android启动界面
    android intent隐式调用之一个应用程序启动另一个应用程序(转载)
    在android程序中打开另一个应用程序
    Android Intent 用法全面总结(转载)
    Android显示GIF动画(转载)
    Android控件——7种形式的Android Dialog使用举例(转载)
    Android开发 获取当前activity的屏幕截图(转载)
  • 原文地址:https://www.cnblogs.com/lscheng/p/2741747.html
Copyright © 2011-2022 走看看