编程珠玑的一些笔记

位操作: 关于除法, 取模

i >> SHIFT <=> i/32

i&MASK <=> i%32 [大于32的部分(32的倍数)都被与掉]

 

#define N 10000000

#define SHIFT 5

#define MASK 0x1f

#define BITSPERWORD 32

int a[N/BITSPERWORD+1];

 

void set_bit(int i)

{

    a[i>>SHIFT] |= 1<<(i&MASK);

}

 

void clr_bit(int i)

{

    a[i>>SHIFT] &= ~(1<<(i&MASK));

}

 

int test_bit(int i)

{

    return a[i>>SHIFT] & (1<<(i&MASK));

}

 

随机数的产生的相关内容

#include <iostream>

#include <time.h>

#include <stdlib.h>

#include <algorithm>

using namespace std;

 

inline void exchange(int *arr, int i, int j)

{

    int temp = arr[i];

    arr[i] = arr[j];

    arr[j] = temp;

}

 

//一般的rand()产生2^15次方的数量级

//产生一个较大的随机数(2^30数量级)

int bigrand()

{

    return (RAND_MAX)*rand()+rand();

}

 

//产生一个在区间[l, h]之间的随机数

int randint(int l, int h)

{

    return l+bigrand()%(h-l+1);

}

 

//产生m个在[0,n-1]之间的有序的随机数

//Knuth:

//时间O(n), 空间O(1)

void randsortedint_knuth(int m, int n)

{

    for (int i = 0; i < n; i++)

    {

       if(bigrand() % (n-i) < m)

       {

           cout << i << "/n";

           m--;

       }

    }

}

 

//产生m个在[0, n-1]之间的有序的随机数

//弄乱数组法:

//时间O(m*logm), 空间O(n)

void randsortedint_shuffer(int m, int n)

{

    int *arr = new int[n];

    for(int i = 0; i < n; ++i)

       arr[i] = i;

 

    for(int i = 0; i < m; ++i)

       exchange(arr, i, randint(i, n-1));

 

    sort(arr, arr+m);

 

    for(int i = 0; i < m; ++i)

       cout << arr[i] << endl;

}

 

//产生m个在[0,n-1]之间的有序的随机数

//floyd:

//时间:O(m*logm), 空间O(m)

void randsortedint_floyd(int m, int n)

{

    set<int> s;

    for(int i = n-m; i < n; i++)

    {

       int t = bigrand()%(i+1);

       if(s.find(t) == s.end())

           s.insert(t);

       else

           s.insert(i);

    }

 

    for(set<int>::iterator i = s.begin(); i != s.end(); ++i)

       cout << *i << endl;

}

int main()

{

    srand(unsigned(time(NULL)));

    return 0;

}

 

旋转一个向量

: abcdefg -> defgabc

1. 置换法

void juggle_rotate(int rotate_dist, int n)

{

    int cycles = gcd(rotate_dist, n);

    for (int i = 0; i < cycles; ++i)

    {

       int current = i;

       int offset;

        int temp = x[i];

       for(;;)

       {

           offset = (current + rotdist) % n;

           if(offset == i)

              break;

           x[current] = x[offset];

           current = offset;

       }

       x[current] = temp;

    }

    printArray();

}

 

2.

//递归实现

void _rotate_cur(char* arr, int beg, int end, int i)

{

    if(i-beg < end-i+1)

    {

       int cnt = i-beg;

       for(int j = 0; j < cnt; ++j)

       {

           int temp = arr[beg+j];

           arr[beg+j] = arr[end-cnt+1+j];

           arr[end-cnt+1+j] = temp;

       }

       _rotate_cur(arr, beg, end-cnt, i);

    }

    else if(i-beg > end-i+1)

    {

       int cnt = end-i+1;

       for(int j = 0; j < cnt; ++j)

       {

           int temp = arr[beg+j];

           arr[beg+j] = arr[i+j];

           arr[i+j] = temp;

       }

       _rotate_cur(arr, beg+cnt, end, i);

    }

    else

    {

       int cnt = i-beg;

       for(int j = 0; j < cnt; ++j)

       {

           int temp = arr[beg+j];

           arr[beg+j] = arr[i+j];

           arr[i+j] = temp;

       }

    }

}

 

void _rotate(char* arr, int n, int i)

{

    _rotate_cur(arr, 0, n-1, i);

}

 

//迭代实现

void swap(int i, int j, int k) /* swap x[i..i+k-1] with x[j..j+k-1] */

{

    int t;

    while (k-- > 0) {

       t = x[i]; x[i] = x[j]; x[j] = t;

       i++;

       j++;

    }

 

}

 

void gcdrot(int rotdist, int n)

{

    int i, j, p;

    if (rotdist == 0 || rotdist == n)

       return;

    i = p = rotdist;

    j = n - p;

    while (i != j) {

       if (i > j) {

           swap(p-i, p, j);

           i -= j;

       } else {

           swap(p-i, p+j-i, i);

           j -= i;

       }

    }

    swap(p-i, p, i);

}

 

寻找第一次出现的某个元素的二分查找法

#include <iostream>

using namespace std;

 

int search1(int* x, int n, int t)

{

    int l = -1, u = n;

    while (l+1 != u)

    {

       int m = (l+u) >> 1;

       if (x[m] < t)

           l = m;

       else

           u = m;

    }

    int p = u;

    if(p >= n || x[p] != t)

       p = -1;

    return p;

}

 

int search2(int* x, int n, int t)

{

    int low = 0, high = n-1;

    int p = -1;

    while (low <= high)

    {

       int mid = (low+high)>>1;

       if(x[mid] == t)

       {

           p = mid;

           high = mid-1;

       }

       else if(t > x[mid])

           low = mid+1;

       else

           high = mid-1;       

    }

    return p;

}

 

int main()

{

    int arr[] = {1,2,2,2,2,4,5,6,6};

    cout << search1(arr, 9, 2) << endl;

    cout << search2(arr, 9, 6) << endl;

    return 0;

}

 

 

快速排序, Shell排序

#include <iostream>

#include <time.h>

#include <stdlib.h>

#define N 1000

using namespace std;

 

inline void exchange(int *arr, int i, int j)

{

    if(i == j)

       return;

 

    int temp = arr[i];

    arr[i] = arr[j];

    arr[j] = temp;

}

 

void print_array(int *arr, int n)

{

    for(int i = 0; i < n; ++i)

       printf("%d ", arr[i]);

    printf("/n");

}

 

int partition1(int *arr, int l, int h)

{

    int j = l;

    for(int p = l+1; p <= h; ++p)

       if(arr[p] < arr[l])

           exchange(arr, p, ++j);

 

    exchange(arr, l, j);

    return j;

}

 

int partition2(int *arr, int l, int h)

{

    int i = l+1, j = h;

    while (1)

    {

       while (i <= h && arr[i] < arr[l])

           i++;

       while (arr[j] > arr[l])

           j--;

       if(i > j)

           break;

       exchange(arr, i++, j--);

    }

    exchange(arr, l, j);

    return j;

}

 

//add atferwards 2010-08-01

int partition3(int *arrint lint h)

{

    int i = lj = h;

    int temp = arr[l]; 

    while (i < j)

    {

       while(i < j && arr[j] >= temp)

           j--;

       arr[i] = arr[j];

       while(i < j && arr[i] <= temp)

           i++;

       arr[j] = arr[i];

    }

    arr[i] = temp;

    return j;

}

 

void quick_sort1(int *arr, int l, int h)

{

    if(l < h)

    {

       int p = partition1(arr, l, h);

       quick_sort1(arr, l, p-1);

       quick_sort1(arr, p+1, h);

    }

}

 

void quick_sort2(int *arr, int l, int h)

{

    if(l < h)

    {

       int p = partition2(arr, l, h);

       quick_sort2(arr, l, p-1);

       quick_sort2(arr, p+1, h);

    }

}

 

void shell_sort(int *arr, int n)

{

    int h;

    for(h = 1; h < n; h = 3*h + 1)

       ;

 

    for(h /= 3; h >= 1; h /= 3)

    {

       for(int i = h; i < n; ++i)

       {

           for(int j = i; j >= h; j -= h)

              if(arr[j-h] > arr[j])

                  exchange(arr, j, j-h);

              else

                  break;

       }

    }

}

 

//寻找第k大的元素

void find_kth(int *arr, int l, int h, int k)

{

    if (l < h)

    {

       int p = partition1(arr, l, h);

       if(k < p)

           find_kth(arr, l, p-1, k);

       else if(k > p)

           find_kth(arr, p+1, h, k);

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值