题目要求:
问题1:在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。
问题2:一个文件,内含一千万行字符串,每个字符串在1k以内,要求找出所有相反的串对,如abc和cba。
问题3:STL的set用什么实现的?为什么不用hash?
题目分析:
问题1分析:
假设int数组为data[]。
用两个数组a、b作为辅助数组,a[i]、b[i]分别保存从左到i最大的数和从右到i的最小数,需要遍历两次data。
然后再遍历一遍原数组data[],将所有的data[i]>=a[i-1]&&data[i]<=b[i]的data[i]找出即可。
-----改进-------
不要b数组,初始化a数组之后,直接倒序遍历data{],用一个临时变量min保存到目前为止的最小数,然后找出满足data[i]>=a[i-1]&&data[i]<=min的即可。
结果:少遍历了一次数组data,少了一个辅助数组b[]。
问题2分析:
1000W*1k = 10G.
根据实际内存,把该文件的数据hash散列到n个小文件file,每个小文件大小大约为10G%n.hash(string)%n = k(其中k∈[0,n),然后把该string放入到file[k]中
把小文件依次读进内存存入set<string>中,每次读入的字符串倒序后到set<string>中查找,如果有则输出,同时删除set<string>中的该字符串;如果没有则把输入的字符串压入到set<string>中。
问题3分析:
set底层实现方式为RB树(即红黑树),红黑树之后会在博客中专题讲解,主要对红黑树插入和删除用伪码的形式讲解。
首先set,不像map那样是key-value对,它的key与value是相同的。关于set有两种说法,第一个是STL中的set,用的是红黑树;第二个是hash_set,底层用的是hash table。红黑树与hash table最大的不同是,红黑树是有序结构,而hash table不是。但不是说set就不能用hash,如果只是判断set中的元素是否存在,那么hash显然更合适,因为set 的访问操作时间复杂度是log(N)的,而使用hash底层实现的hash_set是近似O(1)的。然而,set应该更加被强调理解为“集合”,而集合所涉及的操作并、交、差等,即STL提供的如交集set_intersection()、并集set_union()、差集set_difference()和对称差集set_symmetric_difference(),都需要进行大量的比较工作,那么使用底层是有序结构的红黑树就十分恰当了,这也是其相对hash结构的优势所在。
代码实现:
问题1代码
</pre><pre name="code" class="cpp">/*
author chengzhuwei
*/
#include <iostream>
using namespace std;
void Find(int *data,int n);
int main(void)
{
int data[] = {3,2,6,9,8};
Find(data,5);
data[4] = 12;
Find(data,5);
return 0;
}
void Find(int *data,int n)
{
if(data==NULL || n<=0)
return ;
int *a = new int[n];
int *b = new int[n];
int max = data[0];
a[0] = data[0];
for(int i = 1;i<n;i++)
{
if(data[i]>max)
max = data[i];
a[i] = max;
}
int min = data[n-1];
b[n-1] = data[n-1];
for(int i = n-2;i>=0;i--)
{
if(data[i]<min)
min = data[i];
b[i] = min;
}
cout << "满足的元素有:";
for(int i = 1;i<n;i++)
{
if(data[i]>=a[i-1] && data[i]<=b[i])
cout << data[i] << " ";
}
cout << endl << "-----------------" << endl;
}
问题1改进代码
#include <iostream>
using namespace std;
void Find(int *data,int n);
int main(void)
{
int data[] = {3,2,6,9,8};
Find(data,5);
data[4] = 12;
Find(data,5);
return 0;
}
void Find(int *data,int n)
{
if(data==NULL || n<=0)
return ;
int *a = new int[n];
int *b = new int[n];
int max = data[0];
a[0] = data[0];
for(int i = 1;i<n;i++)
{
if(data[i]>max)
max = data[i];
a[i] = max;
}
int min = data[n-1];
cout << "满足的元素有:";
for(int i = n-1;i>=1;i--)
{
if(data[i]<min)
min = data[i];
if(data[i]>=a[i-1] && data[i]<=min)
cout << data[i] << " ";
}
cout << endl << "-----------------" << endl;
}