位操作: 关于除法, 取模
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 *arr, int l, int h)
{
int i = l, j = 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);
}