编程珠玑第二章

1、给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中一32位整数。

1、在文件中至少存在这样一个数?

2、如果有足够的内存,如何处理?

3、如果内存不足,仅可以用文件来进行处理,如何处理?

答案:

1、32位整数,包括-2146473648~~2146473647,约42亿个整数,而文件中只有40亿个,必然有整数少了。

2、如果采用位数思想来存放,则32位整数最多需要占用43亿个位。约512MB的内存空间。

    可以采用前一章的位处理方法。然后判断每个int是否等于-1。因为-1的二进制表示是全1的。如果不等于-1。那么说明某一位没有置位。需要进行处理。

3、内存不足,假如只有1M内存,可以采用如下思想:

    利用桶排序,划分多个桶,采用64位长整型数据记录每个桶中的数据个数,则1M内存可以分为2^20/8=2^17个桶。

    则每个桶理论上都应该可以记录2^32/2^17=2^15个数据,所有划分桶的区间为0~2^15、2^15~2^16、3*2^15~4*2^15...

    将整个文件读取完成之后,找出记录小于2^15对应的桶,然后将文件再读取一遍,这次可以利用位图排序,找出这个桶区间不存在的整数。

2、字符串循环移位,比如abcdef 左移三位,则变成defabc  (ba=(a的转置b的转置)的转置)

_rev(0, i)          

_rev(i, len)

_rev(0, len)

3、给定一个单词集合,找出可以相互转换的集合。比如abc bca cba都可以相互转换。

1.  单词内部排序,排好序的单词作为map的键(string类型)

2.  键值相同的初始元素压入map的值(vector<string>)中

3.  map一个键对应一个vector(多个值)

对应代码:

4.	void gen_label(vector<string> &dict, map<string, vector<string> >&rec) 
5.	{ 
6.	for (int i = 0; i < dict.size(); ++i) 
7.	{ 
8.	string line = dict[i]; 
9.	sort(line.begin(), line.end()); 
10.	rec[line].push_back(dict[i]); 
11.	} 
12.	
13.	for (map<string, vector<string> >::iterator iter = rec.begin(); 
14.	iter != rec.end(); ++iter) 
15.	{ 
16.	copy((iter->second).begin(), (iter->second).end(), ostream_iterator<string>(cout , " ")); 
17.	cout << endl; 
18.	} 
19.	} 


 

你可能感兴趣的:(编程珠玑第二章)