Вложенный l oop и нехватка памяти в dart - PullRequest
2 голосов
/ 14 июля 2020

Я попытался создать простую программу генератора случайных чисел, используя коды дедупликации во вложении для l oop. Но когда я попытался запустить этот код на dartpad или android studio, два или три раза сработали, и после этого у меня появилось сообщение «нехватка памяти». Есть ли проблемы с моими кодами?

import 'dart:math';

void main() {
  final myNum = <int>[];
  final random = Random();
  int num;

  for (int i = 0; i < 6; i++) {
    num = random.nextInt(45) + 1;
    myNum.add(num);

    for (int j = 0; j < i; j++) {
      if (myNum[i] == myNum[j]) {
        i--;
        break;
      }
    }
  }

  print(myNum);
}

1 Ответ

2 голосов
/ 14 июля 2020

Причина в том, что DartPad сначала показывает вывод только тогда, когда больше нет работы (например, ожидание чего-то asyn c или выполнение программы).

В вашем случае ваша программа содержит infinite l oop, поэтому программа будет работать бесконечно, добавляя элементы в список, пока у вас не закончится память. Это можно увидеть, если вы добавите дополнительное ведение журнала в свою программу и запустите ее в DartVM, который печатает во время работы программы.

Вы можете найти проблему здесь:

    for(int j=0; j<i; j++){
      if(myNum[i]==myNum[j]){
        i--;
        break;
      }
    }

Там являются лучшими способами обнаружения нескольких значений (и некоторые могут утверждать, что вместо этого следует использовать Set), но основная проблема заключается в том, что вы никогда не удаляете обнаруженный элемент из списка. Вместо этого вы просто считаете i в обратном порядке. При вставке элементов в список вы используете:

    myNum.add(num);

Что просто продолжает добавлять элементы в существующий список значений. Итак, ваша программа работает нормально до тех пор, пока if(myNum[i]==myNum[j]) не станет истинным, что произойдет случайным образом (а много времени никогда не произойдет, поэтому вы часто программируете хорошо).

Вы должны добавить myNum.removeLast() в ваш лог c, как показано здесь:

    for (int j = 0; j < i; j++) {
      if (myNum[i] == myNum[j]) {
        i--;
        myNum.removeLast();
        break;
      }
    }

Тогда все работает как положено.

Обновление с примером более простого решения

A Set не может содержать одно и то же значение несколько раз. Поэтому, если мы попытаемся вставить элемент, который уже является частью Set, длина не изменится. Таким образом, мы можем просто сделать следующее:

import 'dart:math';

void main() {
  final myNum = <int>{};
  final random = Random();

  while (myNum.length != 6) {
    myNum.add(random.nextInt(45) + 1);
  }

  print(myNum.toList()); // [2, 23, 40, 35, 39, 22]
}

Еще более короткое решение

Если вы хотите минимизировать код, а также иметь стабильное время выполнения, вы также можете сделать следующее:

void main() {
  print((List.generate(45, (index) => ++index)..shuffle()).sublist(0, 6)); // [6, 41, 12, 2, 11, 42]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...