#dart
Вопрос:
У меня есть два списка чисел, один от 0 до 100, а другой от 0 до 30. Как сгенерировать комбинацию случайных чисел из этих списков при нажатии кнопки, не повторяя одну и ту же комбинацию в течение одного дня в flutter
import 'dart:math';
Num1 = Random().nextInt(100); Num2 = Random().nextInt(30);
DateTime now = new DateTime.now();
DateTime date = new DateTime(now.year, now.month, now.day);
При нажатии кнопки в один и тот же день одна и та же комбинация цифр не должна возникать.
Пример: При первом нажатии кнопки скажите
Num1 = 4
и Num2 = 5
Когда кнопка нажата в другое время в тот же день, предыдущие результаты Num1= 4
и Num2= 5
не должны возникать.
Пожалуйста, опубликуйте немного логики..спасибо
Ответ №1:
Насколько я вижу, вы можете использовать две разные стратегии. Вы можете либо отслеживать созданные вами пары, либо отслеживать их. Или вы можете сгенерировать все пары, сохранить их в коллекции и удалить из этой коллекции, когда вы предоставите случайную пару.
Я создал следующий пример последнего предложенного решения:
import 'dart:collection';
void main() {
final generator = RandomPairGenerator(maxNum1: 100, maxNum2: 30);
print(generator.getRandomAndUniquePair()); // (50, 27)
print(generator.getRandomAndUniquePair()); // (51, 12)
print(generator.getRandomAndUniquePair()); // (89, 16)
print(generator.getRandomAndUniquePair()); // (29, 9)
print(generator.getRandomAndUniquePair()); // (28, 0)
}
class RandomPairGenerator {
final Queue<Pair> _pairs;
RandomPairGenerator({required int maxNum1, required int maxNum2})
: _pairs = Queue.of([
for (var num1 = 0; num1 < maxNum1; num1 )
for (var num2 = 0; num2 < maxNum2; num2 ) Pair(num1, num2)
]..shuffle());
Pair getRandomAndUniquePair() => _pairs.removeFirst();
}
class Pair {
final int num1, num2;
Pair(this.num1, this.num2);
@override
String toString() => '($num1, $num2)';
}
Вместо того, чтобы вызывать генератор случайных чисел для каждой пары , проще просто сгенерировать все возможные пары в a List
, перемешать List
и затем сохранить их в a Queue
, которые оптимизированы для удаления (и добавления) элементов либо с начала, либо с начала.
Редактировать
Вот (не очень эффективный) пример другого подхода, при котором мы сохраняем генерируемые нами числа, чтобы не генерировать их снова:
import 'dart:math';
import 'package:quiver/core.dart';
void main() {
final generator = RandomPairGenerator(maxNum1: 2, maxNum2: 2);
print(generator.getRandomAndUniquePair()); // (8, 12)
print(generator.getRandomAndUniquePair()); // (81, 6)
print(generator.getRandomAndUniquePair()); // (53, 21)
print(generator.getRandomAndUniquePair()); // (81, 6)
print(generator.getRandomAndUniquePair()); // (58, 18)
}
class RandomPairGenerator {
final int maxNum1;
final int maxNum2;
final Random _random = Random();
final Set<Pair> _previousPairs = {};
RandomPairGenerator({required this.maxNum1, required this.maxNum2});
Pair getRandomAndUniquePair() {
Pair pair;
do {
pair = Pair(_random.nextInt(maxNum1), _random.nextInt(maxNum2));
} while (!_previousPairs.add(pair));
return pair;
}
}
class Pair {
final int num1, num2;
Pair(this.num1, this.num2);
@override
String toString() => '($num1, $num2)';
@override
int get hashCode => hash2(num1, num2);
@override
bool operator ==(Object other) =>
other is Pair amp;amp; other.num1 == num1 amp;amp; other.num2 == num2;
}
ПРИМЕЧАНИЕ: Основная проблема с этим решением заключается в том, что стоимость выполнения будет бесконечной, если мы попытаемся сгенерировать больше возможных чисел. Причина в том, что мы на самом деле просто пытаемся сгенерировать а Pair
, а затем проверяем, было ли это Pair
уже сгенерировано.
Чем больше Pair
мы создали в прошлом, тем меньше доступно. Таким образом, вероятность случайного создания равного по возрастет, и, следовательно, потребуется больше циклов, пока мы не получим уникальный Pair
.
Я не уверен, сможем ли мы добиться большего успеха с помощью этого подхода, если не сделаем что-то подобное моему предыдущему решению.
ПРАВКА 2
Я думаю, что лучшее, что вы можете сделать, это объединить два решения в нечто подобное:
import 'dart:collection';
import 'package:quiver/core.dart';
void main() {
final generator = RandomPairGenerator(
maxNum1: 2, maxNum2: 2, previousGenerated: {const Pair(1, 1)});
print(generator.getRandomAndUniquePair()); // (0, 1)
print(generator.getRandomAndUniquePair()); // (1, 0)
print(generator.getRandomAndUniquePair()); // (0, 0)
print(generator.previousGenerated); // {(1, 1), (1, 0), (0, 0), (0, 1)}
print(generator.getRandomAndUniquePair()); // Exception: No more random Pairs available!
}
class RandomPairGenerator {
final Set<Pair> _previousGenerated;
final Queue<Pair> _pairs;
RandomPairGenerator(
{required int maxNum1,
required int maxNum2,
Set<Pair>? previousGenerated})
: _pairs = Queue.of([
...{
for (var num1 = 0; num1 < maxNum1; num1 )
for (var num2 = 0; num2 < maxNum2; num2 ) Pair(num1, num2)
}.difference(previousGenerated ?? {})
]..shuffle()),
this._previousGenerated = previousGenerated ?? {};
Pair getRandomAndUniquePair() {
if (_pairs.isEmpty) {
throw Exception('No more random Pairs available!');
}
final pair = _pairs.removeFirst();
_previousGenerated.add(pair);
return pair;
}
Set<Pair> get previousGenerated => {..._previousGenerated};
}
class Pair {
final int num1, num2;
const Pair(this.num1, this.num2);
@override
String toString() => '($num1, $num2)';
@override
int get hashCode => hash2(num1, num2);
@override
bool operator ==(Object other) =>
other is Pair amp;amp; other.num1 == num1 amp;amp; other.num2 == num2;
}
С помощью этого вы можете предоставить Set
список уже сгенерированных Pair
объектов и получить генератор, который их не генерирует. Вы также можете извлечь a Set
из всех чисел, которые он уже сгенерировал, чтобы сохранить его и использовать в следующий раз, когда вам понадобится создать a RandomPairGenerator
.
Комментарии:
1. Спасибо за решение.. Когда пары генерируются в каком-то другом экземпляре или в какое-то другое время в этот день, есть вероятность, что пара повторится..
2. Вместо того, чтобы генерировать все пары в начале и хранить в очереди, мы можем вызвать случайную пару один раз и сохранить ее в массиве списка.. Когда кнопка будет нажата в следующий раз, проверьте условие, если оно возникло раньше, а затем сгенерируйте другое число и сохраните его в приведенном выше массиве..Можем ли мы сделать так?
3. @AzReddy Ну, мы никогда не сможем создать генератор, который защитит вас от повторяющихся шаблонов, если у нас нет центрального экземпляра, который предоставляет указанные номера (например, сервер). Вопрос о том, следует ли вам сгенерировать все или сохранить сгенерированные данные, в основном связан с эффективностью и количеством чисел, которые вы собираетесь сгенерировать. Но я приведу вам пример сохранения чисел, которые у нас уже есть.