How to generate a non-repeated ordered sequence of M random integers in the range of [0, maxval]

Source: Internet
Author: User

Here we call the data structure to be generated intset, and the interface definition is as follows:

Class intseibd {public: intseibd (INT maxelements, int maxval); void insert (int t); int size (); void report (int * V ); // write elements in the set to vector v };

 

An example is as follows:

void gensets(int m,int maxval){    int *v = new int[m];    IntSetImp S(m,maxval);    while(S.size()<m) {        S.insert(bigrand()%maxval);    }    S.report(v);    for (int i = 0; i < m; ++i)    {        cout<<v[i]<<"\n";    }}

 

Next we will discuss how to implement this problem, and use various data structures to implement the functions we want and compare their performance.

1: Use a powerful and general set Template

class IntSetSTL{private:    set<int> S;public:    IntSetSTL(int maxelements,int maxval){}    int size(){return S.size();}    void insert(int t){S.insert(t);}    void report(int *v)    {        int j=0;        set<int>::iterator i;        for(i=S.begin();i!=S.end();++i)        {            v[j++]=*i;        }    }};

The corresponding parts of the standard template library are basically used.

2: compared to the standard template library, we can use the simplest structure-array to implement a set of resumes.

Class intsetarray {PRIVATE: int N, * X; // n number of elements to be saved, and X to save the array public: intsetarray (INT maxelements, int maxval) {x = new int [1 + maxelements]; n = 0; X [0] = maxval; // as the Sentinel, maxval is always at the end of the sorted element} int size () {return N;} void insert (INT t) {int I; // record for (I = 0; X [I] <t; I ++ ); if (X [I] = T) return; // already in array for (Int J = N; j> = I; j --) X [J + 1] = x [J]; X [I] = T; n ++} void report (int * V) {for (INT I = 0; I <n; ++ I) {v [I] = x [I] ;}}};

 

If the Implementation knows the size of the array (SET), the array will be a relatively ideal structure, because the array is ordered and supports random access, you can use binary search to create a search function with the running time of O (logn ).

3: If you do not know the size of the set, the linked list will be the preferred structure of the set, and the linked list will save the overhead of element movement during insertion.

class IntSetList{private:    int n;    struct node    {        int val;        node *next;        node(int v,node *p){val=v;next=p;}    };    node *head,*sentinel;    node *rinsert(node *p,int t)    {        if(p->val<t) p->next=rinsert(p->next,t);        else if(p->val>t)        {            p=new node(t,p);            n++;        }        return p;    }public:    IntSetList(int maxelements,int maxval)    {        head=sentinel=new node(maxval,0);        n=0;    }    int size(){return n;}    int insert(int t){head=rinsert(head,t);}    void report(int *v)    {        int j=0;        for(node *p=head;p!=sentinel;p=p->next) v[j++]=p->val;    }};

4: The architecture supporting quick search and Insertion-Binary Search Tree

class IntSetBST{private:    int n,*v,vn;    struct node    {        int val;        node *left,*right;        node(int i){val=i;left=right=0;}    };    void rinsert(p,t)    {        if(p==0)        {            p= new node(t);            n++;        }        else if(t<p->val) p->left=rinsert(p->left,t);        else if(t>p->val) p->right=rinsert(p->right,t);        return p;    }    void traverse(p)    {        if(p==0) return;        traverse(p->left);        v[vn++]=p->val;        traverse(p->right);    }public:    IntSetBST(int maxelements,int maxval){root=0;n=0;}    int size(){return n;}    void insert(int t) {root=rinsert(root,t);}    void report(int *x){ v=x;vn=0;traverse(root);}};

 

 

5: Now we will see a more advanced structure that uses the integer-bit vector structure.

Class intsetbitvec {PRIVATE: Enum {bitsperword = 32, shift = 5, mask = 0x1f ;}; // bitsperword corresponds to shift, and 0x1f corresponds to 31, that is, 11111, five-digit mask int N, * X, hi; void set (int I) {x [I> shift] |=( 1 <(I & Mask ));} // I & Mask extracts the last five digits of I, 1 <(I & Mask) = 2 (I & Mask) power void CLR (int I) {x [I> shift] & = ~ (1 <(I & Mask);} void test (int I) {return X [I> shift] & (1 <(I & Mask ));} /* I = 42 --> I & Mask 1 <(I & Mask )~ (1 <10) I> shift 42 = 101010 101010 1 <10 = 2 ^ 10 = ~ 10000000000 = 101010> 5 & 11111 = 10000000000 = 01111111111 = 1 ------- 001010 = 10 CLR (I) --> X [I> shift] = 0 set (I) --> X [I> shift] = 0 | (I & Mask) power of 2 (I & Mask) test (I) -> if you have set (I) 2 (I & Mask) power = 2 (I & Mask) power return true otherwise 0 &... = 0 returns false */public: intsetbitvec (INT maxelements, int maxval) {HI = maxval; X = new int [1 + hi/bitsperword]; for (INT I = 0; I <Hi; I ++) CLR (I); n = 0;} int size () {return N;} void insert (INT T) {If (test (I) return; Set (t); N ++;} void report (int * V) {Int J = 0; For (INT I = 0; I <Hi; ++ I) {If (test (I) V [J ++] = I ;}}};

 

The disadvantage of bitwise vectors is that if n is large, the memory required is also large.

6: the final data structure combines the advantages of the linked list and bit vector, and adds an integer to the box sequence.

class IntSetBins{private:    int n,bins,maxval;    struct node    {        int val;        node *next;        node(int v,node *p) { val=v;next=p;}    };    node **bin,*sentinel;    node *rinsert(node *p,int t)    {        if(p->val<t ) p->next=rinsert(p->next,t);        else if(p->val>t)         {            p = new node(t,p);n++;        }        return p;    }public:    IntSetBins(int maxelements,int pmaxval)    {        bins = maxelements;        maxval = pmaxval;        bin = new node*[bins];        sentinel = new node(maxval,0);        for (int i = 0; i < bins; ++i)            bin[i]=sentinel;        n=0;    }    int size() {return n;}    void insert(int t)    {        int i=t/(1+maxval/bins);        bin[i] = rinsert(bin[i],t);    }    void report(int *v)    {        int j=0;        for (int i = 0; i < bins; ++i)            for(node *p = bin[i];p!=sentinel;p=p->next)                v[j++] = p->val;    }    ~IntSetBins();};

 

How to generate a non-repeated ordered sequence of M random integers in the range of [0, maxval]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.