dart - 嵌套循环和飞镖内存不足
问题描述
我尝试使用嵌套 for 循环中的重复数据删除代码制作一个简单的随机数生成器程序。但是当我尝试在 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);
}
解决方案
原因是 DartPad 仅在没有更多工作要做时才首先显示输出(例如等待异步或程序完成)。
在您的情况下,您的程序包含一个无限循环,因此程序将无休止地运行,不断将元素添加到列表中,直到内存不足。如果您在程序中添加一些额外的日志记录并在 DartVM 中运行它,则可以看到这一点,它会在程序运行时打印。
你的问题可以在这里找到:
for(int j=0; j<i; j++){
if(myNum[i]==myNum[j]){
i--;
break;
}
}
有更好的方法来检测多个值(有些人可能会争辩使用 aSet
代替),但主要问题是您永远不会从列表中删除检测到的元素。相反,您只是在倒计时i
。将元素插入您正在使用的列表中时:
myNum.add(num);
这只是继续将元素添加到现有的值列表中。因此,您的程序运行良好,直到if(myNum[i]==myNum[j])
为真,这将随机发生(而且很多时间永远不会发生,这就是为什么您的程序通常看起来很好)。
您应该将 a 添加myNum.removeLast()
到您的逻辑中,如下所示:
for (int j = 0; j < i; j++) {
if (myNum[i] == myNum[j]) {
i--;
myNum.removeLast();
break;
}
}
然后它按预期工作。
更新更简单的解决方案示例
ASet
不能多次包含相同的值。因此,如果我们尝试插入一个已经是长度的一部分的元素,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]
}
推荐阅读
- c# - 如何解析 HTML 文本并将其添加到 MigraDoc 文档
- react-native - 如何添加选择器和选择器项目用户按钮而不是值
- java - 使用 PHP OpenSSL 将 Java AES/ECB/PKCS7Padding/ 代码转换为 PHP
- .net-core - .NET Core XUnit 测试 Azure Dev Ops,包问题
- highcharts - 在 xAxis 中正确设置日期 HighCharts
- node.js - npm start 问题(错误:spawn cmd ENOENT)
- automated-tests - .should('exist') 断言在赛普拉斯上是多余的吗?
- c# - 如何在winforms中使用数据绑定更新组合框
- node.js - Testcafe:在 boundTestRun 中使用测试控制器不起作用
- reactjs - 如何解决这个错误 Minified React error #200; 访问