Programming Pearls Essay 01 续一
04 产生[0,n-1]并且没有重复的k个随机整数。
方法1:在使用Random类时,每次选择不同的随机因子并在Next中划定范围。
这种方法简单容易实现,看上去似乎是可以满足需求的,但我不知道怎么去证明。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _01._04
{
class Program
{
static void Main(string[] args)
{
int n = 1000000;
int[] array = new int[n];
int range = 5000000;
GenRandomInt1(n, array, range);
Console.ReadKey();
}
private static void GenRandomInt1(int n, int[] array, int range)
{
Random random;
for (int i = 0; i < n; i++)
{
random = new Random(DateTime.Now.Millisecond + i);
array[i] = random.Next(0, range);
random = null;
}
}
}
}
方法2:使用内置的HashSet容器,在每一次获取范围内随机数时判断容器内是否已经存在有这个随机数,如果存在就重新算一个随机数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _01._04
{
class Program
{
static void Main(string[] args)
{
int n = 1000000;
int[] array = new int[n];
int range = 5000000;
HashSet<int> hashArray = new HashSet<int>();
GenRandomInt1(n, array, range);
GenRandomInt2(n, range, hashArray);
Console.ReadKey();
}
private static void GenRandomInt2(int n, int range, HashSet<int> hashArray)
{
Random random = new Random();
int i = 0;
for (i = 0; i < n; i++)
{
int temp;
do
{
temp = random.Next(0, range);
} while (hashArray.Contains<int>(temp));
hashArray.Add(temp);
}
}
private static void GenRandomInt1(int n, int[] array, int range)
{
Random random;
for (int i = 0; i < n; i++)
{
random = new Random(DateTime.Now.Millisecond + i);
array[i] = random.Next(0, range);
random = null;
}
}
}
}
网上还有一种不用hash的方法,递归判断数组中是否存在已有的随机数,在这里就不多写了。
05 之前使用的千万数据位图需要占用大概1.25MB内存,在只有1MB内存的情况下,要如何处理。
1MB内存最多能存储数值在800W以内不重复数据,我们可以在读数据的时候将800W之内的数据读入待处理数组,将大于800W的数据放入外存中,即写入硬盘,等处理好前800W之内的数据之后,再来处理后面的数据,这个时候由于剩下的数据都是大于800W的,我们可以将其全部减掉800W来处理以压缩占用的内存。最后将两次处理的结果结合到一块,因为两部分数据几乎是以800W作为分界线的,可以直接拼接到一块。
06 当数值可能重复最多十次的时候,要怎么处理。
我们可以用四个bit(存储范围是[0,15])存储数值个数,那么占用的内存变成了以前的四倍。
07 略
08 在数据前加区号的话要怎么处理
一个区号对应一个数组。
09
使用hashset
10
现代方法是在数据库中用电话号码建立主键并生成索引
11略
12用铅笔