110,533
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace WindowsApplication14
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (int a = 0; a < 65536; a++)
{
container[a] = new List<float>();
}
}
/// <summary>
/// 内存容器
/// </summary>
List<float>[] container = new List<float>[65536];
/// <summary>
/// 可以使用的内存容器最小索引
/// </summary>
uint containerIndex = 0;
/// <summary>
/// 构造数据文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
FileStream data=File.Create("d:\\data.float", 1024 * 1024 * 10);
DateTime bt1 = DateTime.Now;
Random random=new Random();
for (int a = 0; a < 200000000; a++)
{
double temp = random.NextDouble();
int bi1 = random.Next(10000000);
temp = temp * bi1;
float rand = (float)temp;
byte[] array = BitConverter.GetBytes(rand);
data.Write(array,0,4);
}
data.Close();
DateTime bt2 = DateTime.Now;
this.Text=(bt2-bt1).ToString();
}
int addCount = 0;
/// <summary>
/// 将数据加入到容器
/// </summary>
/// <param name="value"></param>
/// <param name="dataFrame"></param>
void AddContainer(float value, uint dataFrame)
{
addCount++;
uint index = dataFrame & 0x7FFF8000;//01111111 11111111 10000000 00000000
index >>= 15;
//以上获得8位指数和8位头尾数组成的索引
if (index >= containerIndex)
{
container[(int)index].Add(value);
}
//每当添加的数据大于1000w时进行整理
if (addCount > 10000000)
{
//计数器清零
addCount = 0;
//容器中数据量的合计
int sumContainerCount = 0;
for (int a = 65535; a >= 0; a--)
{
sumContainerCount += container[a].Count;
if (sumContainerCount >= 10000)
{
//移动可以使用的容器索引,小于此索引的容器不可以使用
containerIndex = (uint)a;
break;
}
}
//清理不可以使用的容器,释放内存
for (int a = 0; a < containerIndex; a++)
{
container[a].Clear();
}
}
}
/// <summary>
/// 合并数据整理输出
/// </summary>
/// <returns></returns>
List<float> Retuen()
{
List<float> R = new List<float>();
for (int a = 65535; a >= containerIndex; a--)
{
R.AddRange(container[a]);
}
//调用.Net内置排序器,其实就是快排
R.Sort();
//将顺序反转
R.Reverse();
//返回10000个最大的数
return R.GetRange(0, 10000);
}
/// <summary>
/// 计算获得1W个最大数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
for (int a = 0; a < 65536; a++)
{
container[a] = new List<float>();
}
containerIndex = 0;
addCount = 0;
FileStream data = File.OpenRead("d:\\data.float");
DateTime bt1 = DateTime.Now;
byte[] array = new byte[4];
while (data.Read(array, 0, 4) > 0)
{
//转换为一个整数结构
uint bi1 = BitConverter.ToUInt32(array,0);
//还原为浮点数
float bf1 = BitConverter.ToSingle(array, 0);
AddContainer(bf1, bi1);
}
data.Close();
Retuen();
DateTime bt2 = DateTime.Now;
this.Text = (bt2 - bt1).ToString();
}
}
}
static float[] GetTop10000()
const int MaxCount = 10000;
const int FloatLength = 65536;
const int ByteLength = FloatLength * 4;
bool isInit = true;
byte[] buf = new byte[ByteLength];
byte[] byteData = new byte[ByteLength];
float[] maxAfterMerge = new float[MaxCount];
float[] maxBeforeMerge = new float[MaxCount];
float[] current = new float[FloatLength];
int readCount;
float[] tempFloats;
byte[] tempBytes;
using (FileStream data = File.OpenRead("data.float"))
{
readCount = data.Read(byteData, 0, ByteLength);
while (readCount == ByteLength)
{
IAsyncResult ar = data.BeginRead(buf, 0, ByteLength, null, null);
Buffer.BlockCopy(byteData, 0, current, 0, ByteLength);
Array.Sort(current);
Array.Reverse(current);
if (isInit)
{
Buffer.BlockCopy(current, 0, maxBeforeMerge, 0, MaxCount);
isInit = false;
}
else
{
Merge(maxAfterMerge, maxBeforeMerge, current);
tempFloats = maxBeforeMerge;
maxBeforeMerge = maxAfterMerge;
maxAfterMerge = tempFloats;
}
readCount = data.EndRead(ar);
tempBytes = byteData;
byteData = buf;
buf = tempBytes;
}
// 需要讨论一下正好读完的情况,否则Merge方法会有逻辑错误
if (readCount == 0)
return maxBeforeMerge;
Buffer.BlockCopy(byteData, 0, current, 0, readCount);
Array.Sort(current, 0, readCount >> 2);
Array.Reverse(current, 0, readCount >> 2);
Merge(maxAfterMerge, maxBeforeMerge, current, readCount >> 2);
return maxAfterMerge;
}
}
public Form1()
{
InitializeComponent();
}
// lz的算法需要的东西
List<float>[] container = null;
container = new List<float>[65536];
for (int a = 0; a < 65536; a++)
{
container[a] = new List<float>();
}
// ...lz的代码
container = null;
private void button1_Click(object sender, EventArgs e)
{
const int numberCount = 1000000000;
const int resultCount = 10000;
double[] resultData = new double[resultCount];
Random random = new Random(1000); // 随机数种子固定,这样保证大家测试的数据一致
long tickCount = Environment.TickCount;
#region 初始化
int count = 0; // 所填的数据个数
#endregion 初始化
for (int i = 0; i < numberCount; i++)
{
double value = random.NextDouble();
#region 处理数据
if (count >= resultCount && value <= resultData[resultCount - 1]) continue;
///////Begin 对分查找
int low = 0;
int high = count - 1;
while (low <= high)
{
int j = (low + high) >> 1; // 除2
if (value < resultData[j])
low = j + 1;
else
{
high = j - 1;
if (value == resultData[j]) low = j;
}
}
if (low < count && low < resultCount - 1)
{
int l = count - low;
if (low + l > resultCount - 1) l--;
Array.Copy(resultData, low, resultData, low + 1, l);
}
resultData[low] = value;
if (count < resultCount) count++;
///////End 对分查找
#endregion 处理数据
}
Console.WriteLine("运算耗时:{0}", Environment.TickCount - tickCount);
#region 采用输出结果
for (int i = 0; i < resultCount; i += resultCount / 10)
{
Console.WriteLine("返回结果[{0}]={1}", i, resultData[i]);
}
#endregion 采用输出结果
}
const int numberCount = 100000000;
//上面的代码是1亿,改成:
const int numberCount = 1000000000;