位图排序
使用位图对[0..N-1]中不同的整数进行排序
/* bitmap sort -- Sort distinct integers in the range [0..N-1] */
#include <stdio.h>
#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 main()
{
int i;
for (i = 0; i < N; i++)
clr(i);
/* Replace above 2 lines with below 3 for word-parallel init
int top = 1 + N/BITSPERWORD;
for (i = 0; i < top; i++)
a[i] = 0;
*/
while (scanf("%d", &i) != EOF)
set(i);
for (i = 0; i < N; i++)
if (test(i))
printf("%d\n", i);
return 0;
}
/* sortedrand.cpp -- output m sorted random ints in U[0,n) */
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int bigrand()
{
return RAND_MAX*rand() + rand();
}
int randint(int l, int u)
{
return l + bigrand() % (u-l+1);
}
void genknuth(int m, int n)
{
for (int i = 0; i < n; i++)
/* select m of remaining n-i */
if ((bigrand() % (n-i)) < m)
{
cout << i << "\n";
m--;
}
}
void gensets(int m, int n)
{
set<int> S;
set<int>::iterator i;
while (S.size() < m)
{
int t = bigrand() % n;
S.insert(t);
}
for (i = S.begin(); i != S.end(); ++i)
cout << *i << "\n";
}
void genshuf(int m, int n)
{
int i, j;
int *x = new int[n];
for (i = 0; i < n; i++)
x[i] = i;
for (i = 0; i < m; i++)
{
j = randint(i, n-1);
int t = x[i]; x[i] = x[j]; x[j] = t;
}
sort(x, x+m);
for (i = 0; i < m; i++)
cout << x[i] << "\n";
}
void genfloyd(int m, int n)
{
set<int> S;
set<int>::iterator i;
for (int j = n-m; j < n; j++)
{
int t = bigrand() % (j+1);
if (S.find(t) == S.end())
S.insert(t); // t not in S
else
S.insert(j); // t in S
}
for (i = S.begin(); i != S.end(); ++i)
cout << *i << "\n";
}
int main(int argc, char *argv[])
{
int m = atoi(argv[1]);
int n = atoi(argv[2]);
genknuth(m, n);
return 0;
}
使用后缀数组,字符串保存在c中,后缀数组为a,C代码:
/* longdup.c -- Print longest string duplicated 1 times */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int pstrcmp(const void *p, const void *q)
{
return strcmp(*(char **)p, *(char **)q);
}
int comlen(char *p, char *q)
{
int i = 0;
while (*p && (*p++ == *q++))
i++;
return i;
}
#define MAXN 5000000
char c[MAXN], *a[MAXN];
int main()
{
int i, ch, temlen, n = 0, maxi, maxlen = -1;
while ((ch = getchar()) != EOF)
{
a[n] = &c[n];
c[n++] = ch;
}
c[n] = 0;
qsort(a, n, sizeof(char *), pstrcmp);
for (i = 0; i < n-1; i++)
{
temlen = comlen(a[i], a[i+1]);
if (temlen > maxlen)
{
maxlen = temlen;
maxi = i;
}
}
printf("%.*s\n", maxlen, a[maxi]);
return 0;
}
正确实现二分查找算法
二分查找可以解决排序数组的查找问题:只要数组中包含T(即要查找的值),那么通过不断缩小包含T的范围,最终就可以找到它。一开始,范围覆盖整个数组。将数组的中间项与T进行比较,可以排除一半元素,范围缩小一半。就这样反复比较,反复缩小范围,最终就会在数组中找到T,或者确定原以为T所在的范围实际为空。对于包含N个元素的表,整个查找过程大约要经过log(2)N次比较。
//copyright@2011 July
//随时欢迎读者找bug,email:zhoulei0907@yahoo.cn。
//首先要把握下面几个要点:
//right=n-1 => while(left <= right) => right=middle-1;
//right=n => while(left < right) => right=middle;
//middle的计算不能写在while循环外,否则无法得到更新。
int binary_search(int array[],int n,int value)
{
int left = 0;
int right = n-1;
//如果这里是int right = n 的话,那么下面有两处地方需要修改,以保证一一对应:
//1、下面循环的条件则是while(left < right)
//2、循环内当array[middle]>value 的时候,right = mid
while (left <= right) //循环条件,适时而变
{
int middle = left + ((right-left)>>1);//防止溢出,移位也更高效。每次循环都需要更新。
if (array[middle] > value)
{
right = middle-1; //right赋值,适时而变
}
else if(array[middle] < value)
{
left = middle+1;
}
else
return middle;
//可能会有读者认为刚开始时就要判断相等,但毕竟数组中不相等的情况更多
//如果每次循环都判断一下是否相等,将耗费时间
}
return -1;
}