大致伪代码如下: int count = 1; string query[m+1]; //为了方便理解,从1开始存 while(scanf("%s",&cur_query)!=EOF) { count++; if(count <= m) { // 如果输入小于m,直接存。 query[count] = cur_query; } else { // 剩余的,就随机一个数,并交换。具体为何,在下述证明可见 int M = random(1, count); if( M < m) { query[M] = cur_query; } }
思路:如果用户查询的数量小于m,那么直接就存起来。如果用户查询的数量大于m,假设为m+i,那么在1-----m+i之间随机产生一个数,如果选择的是前面m条查询进行存取,那么概率为m/(m+i),如果选择的是后面i条记录中的查询,那么用这个记录来替换前面m条查询记录的概率为m/(m+i)*(1-1/m)=(m-1)/(m+i),当查询记录量很大的时候,m/(m+i)== (m-1)/(m+i),所以每个query被抽中的概率是相等的。