1 |
int main( void ){ |
2 |
vector v; |
3 |
for ( int i = 0; i < 100; i++ ) |
4 |
v.push_back( rand () ); |
5 |
sort( v.begin(), v.end() ); |
6 |
for ( int i = 0; i < 100; i++ ) |
7 |
cout << v[i] << endl; |
8 |
return 0; |
9 |
} |
c++中的set容器也可以实现排序的功能,当元素添加到集合中后,set可以自动排序。用迭代器从头到尾遍历就可以得到排序序列。参考:http://www.cplusplus.com/reference/stl/set/
python中列表有sort方法。
list = [3,4,5,6,7]
list.sort()
2.位向量的实现就是用比特位0,1来表示一些特定信息,通常是用数组,每个int中包含32个bits,当我们定位某个位置时,先确定索引是在哪个int中,然后再确定int中的那个位对应索引。我用c语言和c++中的类实现了位向量。我不帖出来了,在github上,https://github.com/fookwood/fkcode/tree/master/bitvector,排版看起来不行= =。。。
c++中有现成的bitset,我猜实现原理应该和以上差不多。
3.位图的实现我用了三种,一个是c语言的(简称cvec),一个是c++的(简称cppvec),还有时c++现成的bitset(简称bitset)。系统排序用的是sort命令,加上-n选项。排序用了c的qsort,c++的sort和c++的set。下面是运行时间。
cvec 1.737 1.001
cppvec 1.769 1.033
bitset 2.644 1.908
系统sort命令 5.290 4.554
qsort 2.081 1.345
sort 2.802 2.066
set 5.921 5.185
输入输出的时间是0.736s。左右分别为带输入输出和不带的。
可以看出两种语言位图的实现都是效率最高的,c++中的bitset,set,sort虽然效率上差了点,但是实现上非常方便,而且能保证一定的正确性。系统的排序实在方便,一句命令就可以搞定( sort -n < in -o out ).
4.生成[0,n)的之间k个不重复的随机整数。
1 |
#include<iostream> |
2 |
#include<cstdlib> |
3 |
#include<algorithm> |
4 |
#include<cstdio> |
5 |
using namespace std; |
6 |
const int N = 10000000; |
7 |
const int K = 10000000; |
8 |
int randint( int l, int r ){ |
9 |
return rand () % ( r-l ) + l; |
10 |
} |
11 |
int a[ N ]; |
12 |
int main( void ){ |
13 |
for ( int i = 0; i < N; i++ ) |
14 |
a[i] = i; |
15 |
for ( int i = 0; i < K; i++ ){ |
16 |
swap( a[i], a[ randint(i,N) ] ); |
17 |
printf ( "%d\n" ,a[i]); |
18 |
} |
19 |
return 0; |
20 |
} |
如果要想生成这样一个数组,可以直接从头到尾循环,每个数根随机位置交换值就可以。
5.可以将输入文件分成两分,第一份保存[0,5000000)的数,第二个文件保存[5000000,10000000)的数字,然后分别进行排序,所用内存就可以降到1MB以内。如果我们把文件分成k份(每份都存一定区间的数),那么就可以在n的时间,n/k的空间内完成排序。标准答案中说可以在nk时间n/k空间内完成,我对于nk的时间不太明白,把输入文件扫描,然后把数字保存到相应文件,扫一遍应该就可以了。
6.每个整数最多出现10次,那么保存每个数字信息的空间不再是1bit了,可以用4bits来保存,可以类比第五题,可以分成4份,在n/4的空间内完成。同样,当保存数字信息的量变化时,分成更多份,就可以在更小的空间内完成。
7.
数出现超过一次?
当第二次更新的时候,相应位已经是1了,这个时候提示错误。
当输入小于0或者大于等于n?
当输入数字时候对其进行范围判断,忽略或者提示错误。
不是数值?
忽略
8.题目描述中排序包含区号么。。。用一种效率稍逊的算法就是每个区号建立一个set,查找时候的效率是O(logN)的。有木有谁又更好的办法。
9.本题值得一说。
初始化空间需要大量时间,不过我们的应用只需要其中一点点空间,比如1000000的位图,我们只用到其中的10位,怎样节省时间?题目中提示,可以用额外的正比于向量大小的空间。我当时直接看的答案,到晚上搜了搜才看懂。
10.类似于取快递,根据电话号码的最后一位或者最后两位进行分类,类似于哈希的思想,用顺序遍历来处理碰撞。不能用开头的原因是很多电话号码的前面都是一样的,比如手机号码都是以1开头的。而且最后一位的分布比较随机、均匀。
11.= =答案竟然说飞鸽传书。
12.铅笔? T.T ....