Dart 检查地图是否存在重复值的最快方法?

Dart 检查地图是否存在重复值的最快方法?,dart,Dart,给定一个映射、赋值,检查Dart中是否包含任何重复值的最快方法是什么?我目前正在使用一个由地图值组成的集合,并对照原始地图检查其长度,这当然有效,但我想知道是否有一个性能特别好的替代方案 Set d=新的Set.from(赋值); if(d.长度

给定一个映射、赋值,检查Dart中是否包含任何重复值的最快方法是什么?我目前正在使用一个由地图值组成的集合,并对照原始地图检查其长度,这当然有效,但我想知道是否有一个性能特别好的替代方案

Set d=新的Set.from(赋值);
if(d.长度<赋值.长度){
return false;//表示此上下文中有重复项
}
编辑: 尝试了@mezoni为我的程序修改的解决方案,但它实际上比我的原始版本运行得慢一点。它可能更多地与恒定时间有关,而不是其他任何事情。

List values=new List.from(assignment.values);
集合=新集合();
对于(变量i=0;i
就复杂性而言,您无法更快地获得任何东西。创建集合并用贴图的值填充它在元素数量上是线性的。很明显,你必须浏览所有的价值观,所以你没有比这更好的了


也许你能找到一个常数因子更小的解,但这还不清楚。特别是对于较大的集合,我认为集合解是非常有效的。

这更像是一个算法问题,而不是Dart问题。在任何情况下,您都必须对照其他值检查每个值,给出
n-1+n-2+…+n-(n-1)
检查,或
n^2/2
。通过编程,创建一个集合很容易,但是您也可以生成一个数组,对数组进行排序,然后迭代一次以检查重复项。以O(n log n)结束。

快速测试方式(如果您确实需要更好的性能):

void main(){
//来自地图的值
var值=[1,2,3,2,1,3,2,1];
变量长度=value.length;
变量集=新集();
var duplicate=false;
//只作统计用途
var统计=0;
对于(变量i=0;i
输出:

Duplicate: true
Performed in 4 iteration(s) from 8 possible
附言

第一个示例建议与
列表
值一起使用

但是因为
Map.values
不是
List
而是
Iterable
,所以更有效的方法是不要将它们转换为
List
,而是按原样使用

下面是用于
Iterable
对象的修改示例

它将更快地工作,因为在此算法中,不需要将所有值转换为
列表
对象,因为它不希望毫无例外地使用所有元素

相反,它希望在原始源上使用尽可能少的访问操作。如果源代码支持访问值的延迟操作(如
Iterable
),这将更好

void main(){
//来自地图的值
var值=[1,2,3,2,1,3,2,1];
var赋值={};
变量长度=value.length;
var-key=0;
for(值中的var值){
赋值[键++]=值;
}
变量集=新集();
var duplicate=false;
//只作统计用途
var统计=0;
for(assignment.values中的var值){
统计学++;
如果(!set.add(value)){
重复=正确;
打破
}
}
打印(“副本:$Duplicate”);
打印(“可能从$length开始在${statistics}迭代中执行”);
}

制作一个集合不会在第一次复制时停止,因此您可以添加元素,直到添加第一个不会改变集合大小的元素,此时您知道存在一个副本。谢谢@mezoni的回答。我在代码中做了一些测试,用您的修改版本替换了我的旧代码。原来的车实际上跑得快了一点。我对问题进行了编辑,以包含我对你的问题的版本。@davecom我会更新你修改后的问题的答案。这确实是一个很好的技巧。如果使用通用排序算法,它可能会丢失常量因子,因为在检查重复项之前复制并排序所有值,但是集合解决方案可以在第一次添加它已经看到的元素时停止,但是如果在排序算法第一次发现重复项时退出,它也应该非常有效。即使元素不可比较,您也应该能够按hashCode对它们进行排序,然后只比较相等的hashCode是否相等。而不是在
for
循环中使用
(var i=0;i
,您可以使用
(赋值中的var元素)