编程珠玑 chapter 1
仔细分析小问题可以带来巨大的实际好处。定义恰当的问题,需求分析:问题的输入--问题的输出---约束条件
位图数据结构可以很方便的处理索引问题,有限域中的稠集。
多通道算法,多个输入通道或者多个输出
时间和空间的权衡,二者可以转换效率,用时间换取空间或用空间换取时间
简单的设计:设计师的至高境界不是他能不能再往作品中添加什么东西,而是他不能从中取走什么东西。
顺序查找带有冲突解决的开放式散列:商店根据用户的电话最后两位作为散列索引将用户的订单放入10*10的桶数组中。电话的最后两位非常随机,因此是非常优秀的散列函数。
/************************************************************************/
/* sort 10000000 different numbers and each number has 7 digits */
/************************************************************************/
//solution 1. use C qsort
int intcomp(int *x, int *y){
return *x-*y;
}
int a[10000000];
int main(void){
int i, n=0;
while (scanf("%d",&a[n])!=EOF)
n++;
qsort(a,n,sizeof(int),intcomp);
for (i = 0; i<n; i++)
printf("%d\n",a[i]);
return 0;
}
//solution 2. use C++ STL Set
int main(void){
set<int> S;
int i;
set<int>::iterator j;
while(cin>>i)
S.insert(i);
for(j = S.begin(); j != S.end(); ++j)
cout<<*j<<"\n";
return 0;
}
//solution 3. use bit map
/************************************************************************/
/* 每一位来表示一个数,如果有这个数,则把相应位置1,顺序读入所有的
数字,此例中10000000需要10000000/8=125万字节的存储空间,如果已知电话号码
不可能以0、1开头,则又可以减少2000000/8=25万字节。然后再根据位数一次
写出位对应的数字,即排好序。对于重复的数字,可用4位表示一个数字出现
的次数,如果使用2个通道处理,首先使用5000000/8=625000个字的内存排序
0~4999999之间的整数,然后再第二个通道排序5000000~9999999之间的整数,
两个通道同时进行,用空间换取时间的效率。
*/
/************************************************************************/
//some common bit set/clear/test operation defination
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1+N/BITSPERWORD] //the array to store all the bits
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(void){
int i;
for (i = 0; i < N; i++)
clr(i);
while(scanf("%d",&i)!=EOF)
set(i);
for (i = 0; i < N; i++)
if (test(i))
printf("%d\n", i);
return 0;
}
位图数据结构可以很方便的处理索引问题,有限域中的稠集。
多通道算法,多个输入通道或者多个输出
时间和空间的权衡,二者可以转换效率,用时间换取空间或用空间换取时间
简单的设计:设计师的至高境界不是他能不能再往作品中添加什么东西,而是他不能从中取走什么东西。
顺序查找带有冲突解决的开放式散列:商店根据用户的电话最后两位作为散列索引将用户的订单放入10*10的桶数组中。电话的最后两位非常随机,因此是非常优秀的散列函数。
/************************************************************************/
/* sort 10000000 different numbers and each number has 7 digits */
/************************************************************************/
//solution 1. use C qsort
int intcomp(int *x, int *y){
return *x-*y;
}
int a[10000000];
int main(void){
int i, n=0;
while (scanf("%d",&a[n])!=EOF)
n++;
qsort(a,n,sizeof(int),intcomp);
for (i = 0; i<n; i++)
printf("%d\n",a[i]);
return 0;
}
//solution 2. use C++ STL Set
int main(void){
set<int> S;
int i;
set<int>::iterator j;
while(cin>>i)
S.insert(i);
for(j = S.begin(); j != S.end(); ++j)
cout<<*j<<"\n";
return 0;
}
//solution 3. use bit map
/************************************************************************/
/* 每一位来表示一个数,如果有这个数,则把相应位置1,顺序读入所有的
数字,此例中10000000需要10000000/8=125万字节的存储空间,如果已知电话号码
不可能以0、1开头,则又可以减少2000000/8=25万字节。然后再根据位数一次
写出位对应的数字,即排好序。对于重复的数字,可用4位表示一个数字出现
的次数,如果使用2个通道处理,首先使用5000000/8=625000个字的内存排序
0~4999999之间的整数,然后再第二个通道排序5000000~9999999之间的整数,
两个通道同时进行,用空间换取时间的效率。
*/
/************************************************************************/
//some common bit set/clear/test operation defination
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1+N/BITSPERWORD] //the array to store all the bits
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(void){
int i;
for (i = 0; i < N; i++)
clr(i);
while(scanf("%d",&i)!=EOF)
set(i);
for (i = 0; i < N; i++)
if (test(i))
printf("%d\n", i);
return 0;
}
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。