生成随机数数组时出现系统OutOfMemoryException

时间:2017-08-14 10:50:27

标签: c# .net arrays linq memory

我试图使用LINQ创建大量随机数。

我想生成1,000,000个数字,范围从1到2147483647。

以下代码适用于小数字:

var url = 'http://oployeelabs.net/demo/demo_doctorola/doctorola-server/index.php/doctor_panel_api/validation_modified/format/json';
load();
$.ajax({
    url: url,
    data: { cell_no: phone, pass: pass },
    method: 'POST',
    dataType: 'json',
    success: function (data) {
        alert();
        if (data == "false")
        {
            alert("Wrong password");
        }
        else
        {
            localStorage.doctorid = data[0].id;
            localStorage.userinfo = JSON.stringify(data);
            $.ajax({
                url: "http://oployeelabs.net/demo/demo_doctorola/doctorola-server/index.php/api/information/meta-info/location/id/"+data[0].id+"/username/9791a47fef07649b1c3e70749e898153/password/2d593e25d0560b19fd84704f0bd24049/format/json",
                method: 'GET',
                dataType: 'json',
                success: function (dt) {

                    localStorage.Chamberinfo = JSON.stringify(dt);
                    mainView.router.loadPage({ url: 'menu.html', ignoreCache: true, reload: true })
                    $('.toolbar').removeClass('hide');

                }
            });


        }

        //if (data === "ok") {
        //    $(".confirm_appointment").remove();
        //    var anc = "<a id='confirm_appointment' class='confirm_appointment' style='opacity: 0;' href='confirm.html' data-context='{\"slot_id\": \"" + slot_id + "\",\"slot_date\": \"" + slot_date + "\", \"email\": \"contact@john.doe\"}'>profile</a>";
        //    $(document).find('.page_content').append(anc);
        //    $(".confirm_appointment")[0].click();
        //}
        //else {
        //    myApp.hidePreloader();
        //    myApp.alert("", "Sorry, this slot has been booked. Please try with another slot.");
        //}
    },
    error: function (xhr, status, exception) {
        alert(xhr.responseText+" "+status+" "+ exception);
        console.log("Error: " + xhr.responseText + " - " + exception);
    },
    complete: function () {
        myApp.hidePreloader();
        unload();
    }
});

但是在尝试生成大型数组时会产生System.OutOfMemory异常。

实现我想要的最佳方式是什么?

编辑: 感谢您的帮助到目前为止,我已经写了为什么我这样做以及我的完整程序代码:

关于数组,它不应包含重复项。

我正在编写一个程序,它将迭代所有数字,将它们配对并返回它们之间最小差异的对。或者如果它们是重复的,则返回所有具有最小差异的对的列表。

完整的程序代码:

    int[] numbers = Enumerable.Range(1, 2147483647)
                              .OrderBy(x => rnd.Next())
                              .Take(num)
                              .ToArray();

编辑2:

我现在正在获取另一个OutOfMemory异常 static void Main(string[] args) { // Keep running until close while (true) { Console.WriteLine("Write a number:"); Console.WriteLine(ClosestNumbers(Convert.ToInt32(Console.ReadLine()))); } } public static string ClosestNumbers(int num) { string returnString = "\n\nRandom numbers:\n"; returnString += "---------------------------------------\n"; Random rnd = new Random(); // Generate array of {num} random numbers ranging from 1 to 2147483647. int[] numbers = Enumerable.Range(1, 1000000) .OrderBy(x => rnd.Next(1, 2147483647)) .Take(num) .ToArray(); //returnString += string.Join(",", numbers.ToArray()) + "\n"; // Array format: {num1, num2, difference} List<int[]> pairedDifferences = new List<int[]>(); int endPoint = numbers.Length; int difference = 0; for (int i = 0; i < endPoint - 1; i++) { for (int a = i + 1; a < endPoint; a++) { if (numbers[i] > numbers[a]) { difference = numbers[i] - numbers[a]; } else { difference = numbers[a] - numbers[i]; } pairedDifferences.Add(new int[] { numbers[i], numbers[a], difference }); } } int minDiff = pairedDifferences.Min(x => x[2]); List<int[]> minDiffsList = pairedDifferences.Where(x => x[2] == minDiff).ToList(); returnString += "---------------------------------------\n\n\n"; returnString += "Smallest difference(s) found between:\n\n"; foreach (int[] minDiffItem in minDiffsList) { // minDiffItem[0]; // first num // minDiffItem[1]; // second num // minDiffItem[2]; // difference returnString += $"{minDiffItem[0]} and {minDiffItem[1]}, with a difference of {minDiffItem[2]}.\n"; } returnString += "\n\n\n===================================================================\n"; returnString += "===================================================================\n\n\n"; return returnString; } 线。有谁知道更好的方法吗?对不起,这是我第一次这样做。

3 个答案:

答案 0 :(得分:4)

您的代码优化不佳。 Random类允许您指定从中获取随机数的范围。这样你就不需要订购所有东西,这是非常昂贵的。试试这个

int[] numbers = Enumerable.Range(1, 1000000)
                          .Select(i => rnd.Next(1, 2147483647))
                          .ToArray();

修改

以前不清楚是否允许重复。如果是这种情况,我会添加一个HashSet来跟踪已经包含的数字,如果获得的随机数的数量远小于它们必须包含的范围,这就是这种情况。

var memory = new HashSet<int>();
int[] numbers = Enumerable.Range(1, 1000000)
                          .Select(i =>
                          {
                               int number;
                               do
                               {
                                    number = rnd.Next(1, 2147483647);
                               } while (memory.Contains(number));
                               return number;
                          })
                          .ToArray();

另请查看this question以了解有关生成无重复的随机数的更多信息。

答案 1 :(得分:0)

如果需要平衡随机数生成,可以使用以下代码:

const int rangeCount = 1_000_000;
int rangeSize = 2_147_483_647 / rangeCount;

int[] numbers = Enumerable.Range(1, rangeCount)
                          .Select(rangeIndex => 
                           {
                             int from = ((rangeIndex - 1) * rangeSize) + 1;
                             int to = from + rangeSize;

                             return rnd.Next(from, to);
                           })
                          .ToArray();

应为每个2147483647/1000000数字范围产生1个随机数。

答案 2 :(得分:-1)

它与OrderBy函数有关。这是内存使用的O(n),这是你的问题。

O(n)构成线性存储器使用。因此,更多输入意味着线性更多的内存。