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. }