我实现了在100,000整数文件上使用的MergeSort算法。它负责排序并收集文件中的反转。它适用于小型测试阵列,但只要我插入实际文件,就会出现内存不足错误。我如何解决它? MergeSort期间发生错误,我的aux数组中的元素数量为12,500 这是我的代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_1
{
class Program
{
static void Main(string[] args)
{
List<int> data = File2Array("IntegerArray.txt");
int[] unsorted = data.ToArray();
List<string> inversions = new List<string>();
Sort(ref unsorted, ref inversions);
Console.WriteLine("number of inversions is: " + inversions.Count());
Console.ReadLine();
}
public static void Sort(ref int[] unsorted, ref List<string>inversions)
{
int size = unsorted.Length;
if (size == 1)
return;
int mid = size / 2;
int leftSize = mid;
int rightSize = size - leftSize;
int[] left = new int[leftSize];
int[] right = new int[rightSize];
Array.Copy(unsorted, 0, left, 0, leftSize);
Array.Copy(unsorted, mid, right, 0, rightSize);
Sort(ref left, ref inversions);
Sort(ref right, ref inversions);
int[] aux = new int[leftSize + rightSize];
for (int i = 0, j = 0, k = 0; k < aux.Length; k++)
{
if (left[i] < right[j])
{
aux[k] = left[i++];
// if left array is exhausted, copy the remaining right array elements over
if (i == leftSize)
{
Array.Copy(right, j, aux, ++k, rightSize - j);
unsorted = aux;
break;
}
}
else
{
int temp = i;
while (temp < leftSize)
{
inversions.Add(left[temp++] + "-" + right[j]);
}
aux[k] = right[j++];
if (j == rightSize)
{
Array.Copy(left, i, aux, ++k, leftSize - i);
unsorted = aux;
break;
}
}
}
}
public static List<int> File2Array(string file)
{
List<int> data = new List<int>();
using (StreamReader reader = new StreamReader(file))
{
int line;
do
{
int.TryParse(reader.ReadLine(), out line);
data.Add(line);
}
while (!reader.EndOfStream);
}
return data;
}
}
}
答案 0 :(得分:1)
这里有一些代码供您查看。
首先要认识到该文件已经是单个元素的集合。因此,当我们读取文件时,我们可以进行第一次分组/排序。由于数组对于这部分非常不实用,我使用Lists然后将返回转换为int [] []
static int[][] makearrays(string filename)
{
List<List<int>> outval = new List<List<int>>();
using(StreamReader sr = new StreamReader(filename))
{
while(!sr.EndOfStream)
{
int a = 0, b = 0;
a = int.Parse(sr.ReadLine());
if(!sr.EndOfStream)
b = int.Parse(sr.ReadLine());
else
{
outval.Add(new List<int>() { a });
break;
}
if(a > b)
outval.Add(new List<int>() { b, a });
else
outval.Add(new List<int>() { a, b });
}
}
return outval.Select(x => x.ToArray()).ToArray();
}
使用这个数组,我们可以开始其余的分组/排序
这使用递归但内存占用最少:
static int[][] dosort(int[][] input)
{
if(input.Length == 1)
return input;
int i = 1, m = 0;
for(; i < input.Length; i += 2)
{
int limit = Math.Min(input[i].Length, input[i - 1].Length);
int[] temp = new int[input[i].Length + input[i - 1].Length];
int j = 0, k = 0, l = 0;
while(j < input[i].Length && k < input[i - 1].Length)
{
if(input[i][j] < input[i - 1][k])
{
temp[l++] = input[i][j++];
}
else
temp[l++] = input[i - 1][k++];
}
while(l < temp.Length)
{
if(j < input[i].Length)
temp[l++] = input[i][j++];
if(k < input[i - 1].Length)
temp[l++] = input[i - 1][k++];
}
input[m++] = temp;
}
if(input.Length % 2 == 1)
input[m++] = input.Last();
input = input.Take(m).ToArray();
return dosort(input);
}
在我的测试中,100000元素文件的排序时间不到四分之一秒,包括将其读入内存。