dart中嵌套循环且内存不足



我尝试使用嵌套for循环中的重复数据消除代码制作一个简单的随机数生成器程序。但当我尝试在dartpad或android工作室上运行此代码时,有两三次成功了,之后,我得到了";内存不足";消息我的密码有问题吗?

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);
}

原因是DartPad只有在没有更多工作要做时(例如等待异步或程序完成(才会首先显示输出。

在这种情况下,程序包含一个无限循环,因此程序将无休止地运行,不断向列表中添加元素,直到内存耗尽。如果你在程序中添加一些额外的日志记录,并在DartVM中运行它,就会看到这一点,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(),如下所示:

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

然后它按预期工作。

更新更简单的解决方案示例

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]
}

最新更新