海量数据处理面试题

有2.5E个整数数据,找出其中重复的,给定的内存是600M。

由于题目描述的不够清晰,现在假定整数指的是int32,其中有正有负有零,范围就是int32的范围。

可以用编程珠玑里的位图来处理,由于内存只有600M,刚好可以将数据分作正,负和0来处理,这个范围是两个2^31,那就是一次处理位图占用512M的内存。

之前我用byte数组表示位图,有很多繁琐的步骤和数据结构,在分析博客园其他大牛的文章和手头资料之后决定使用BitArray来处理。

总共需要两个位图,一个标志出现过的整数,一个标志这个整数是重复出现的。

程序分作数据生成和处理两个部分。处理数据的时候程序大概占用了500多M。时间用的还蛮多的,占用的CPU时钟数如下:

代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace 生成数据
{
class Program
{
static void Main(string[] args)
{

//GenerateData();
long time = DateTime.Now.Ticks;
ProcessData();
time = DateTime.Now.Ticks - time;
Console.WriteLine("处理数据所花费的时间为{0}", time);
Console.ReadKey();
}

private static void ProcessData()
{
int max = int.MaxValue;
int min = int.MinValue;
BitArray existFlag = new BitArray(max);
BitArray countFlag = new BitArray(max);
byte zeroFlags = 0, minFlags = 0;
using (FileStream data = new FileStream("data", FileMode.OpenOrCreate))
{
int length = (int)(data.Length / sizeof(int)), temp;
var br = new BinaryReader(data);
for (int i = 0; i < length; i++)
{
temp = br.ReadInt32();
if (temp > 0)
{
if (existFlag.Get(temp) == false)
{
existFlag.Set(temp, true);
}
else
{
if (countFlag.Get(temp) == false)
{
countFlag.Set(temp, true);
}
}
}
}

FileStream result = new FileStream("result(大于0).txt", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(result);
for (int i = 0; i < int.MaxValue; i++)
{
if (countFlag.Get(i) == true)
{
sw.Write(i.ToString());
sw.Write(" ");
}
}

existFlag.SetAll(false);
countFlag.SetAll(false);
//现在开始处理负数和0
data.Position = 0;
for (int i = 0; i < length; i++)
{
temp = br.ReadInt32();
if (temp < 0 && temp > min)
{
if (existFlag.Get(Math.Abs(temp)) == false)
{
existFlag.Set(Math.Abs(temp), true);
}
else
{
if (countFlag.Get(Math.Abs(temp)) == false)
{
countFlag.Set(Math.Abs(temp), true);
}
}
}
else if (temp == 0)
{
zeroFlags++;
}
else if (temp == min)
{
minFlags++;
}
}
result = new FileStream("result(小于等于0).txt", FileMode.OpenOrCreate);
sw = new StreamWriter(result);
if (zeroFlags > 1)
{
sw.Write("0 ");
}
for (int i = 0; i < int.MaxValue; i++)
{
if (countFlag.Get(i) == true)
{
sw.Write((-i).ToString());
sw.Write(" ");
}
}
if (minFlags > 1)
{
sw.Write(min);
}
}

}

private static void GenerateData()
{
using (FileStream data = new FileStream("data", FileMode.OpenOrCreate))
{
int n = 250000000;
Random random = new Random();
BinaryWriter bw = new BinaryWriter(data);
int max = int.MaxValue;
int min = int.MinValue;
for (int i = 0; i < n; i++)
{
bw.Write(random.Next(random.Next(min, 0), random.Next(0, max)));
}
}
}
}
}

输出结果分为大于0和小于等于0的。

 

结束。

posted on 2011-12-09 22:30  yukl1n  阅读(2630)  评论(0编辑  收藏  举报

导航