检查Map是否有重复值的最快方法?

时间:2014-03-09 17:46:53

标签: dart

给定一个Map,赋值,检查Dart中是否包含任何重复值的最快方法是什么?我目前正在使用一个由Map的值组成的Set,并根据原始Map检查它的长度,当然这是有效的,但我想知道是否有一个特别高效的替代方案。

Set d = new Set.from(assignment.values);
if (d.length < assignment.length) {
  return false;  // indicates has duplicates in this context
}

编辑: 尝试@ mezoni的解决方案为我的程序修改,但它实际上比我原来的版本慢了一点。它可能与其他任何事情有关。

List values = new List.from(assignment.values);
Set set = new Set();
for (var i = 0; i < assignment.length; i++) {
  if (!set.add(values[i])) {
    return false;
  }
}

3 个答案:

答案 0 :(得分:3)

复杂性明智,你将无法获得更快的速度。创建集合并使用Map的值填充它是元素数量的线性。显然,你必须贯穿所有的价值观,所以你不能做得更好。

也许你可以找到一个具有较小常数因子的解决方案,但目前尚不清楚。特别是对于较大的集合,我认为Set解决方案非常有效。

答案 1 :(得分:2)

这是一个算法问题,而不是Dart问题。无论如何,您必须检查每个值与其他值,检查n-1 + n-2 + ... + n-(n-1)n^2/2。以编程方式,创建一个集合很容易,但您也可以生成一个数组,对数组进行排序,然后迭代一次以检查重复项。以O(n log n)结束。

答案 2 :(得分:1)

Fastets方式(如果你真的需要更好的表现):

void main() {
  // Values from map
  var values = [1,2,3,2,1,3,2,1];
  var length = values.length;
  var set = new Set();
  var duplicate = false;
  // Only for statistics purpose
  var statistics = 0;
  for(var i = 0; i < length; i++) {
    statistics++;
    if(!set.add(values[i])) {
      duplicate = true;
      break;
    }
  }

  print("Duplicate: $duplicate");
  print("Performed in ${statistics} iteration(s) from $length possible");
}

输出:

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

P.S。

可以建议将第一个示例与List值一起使用。

但由于Map.values不是List而是Iterable,因此效率更高,不要将它们转换为List,而是按原样使用。

以下是用于Iterable个对象的修改示例。

它会更快地工作,因为在这个算法中不需要将所有值都转换为List对象,因为它不希望无例外地使用所有元素。

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

void main() {
  // Values from map
  var values = [1,2,3,2,1,3,2,1];
  var assignment = {};
  var length = values.length;
  var key = 0;
  for(var value in values) {
    assignment[key++] = value;
  }

  var set = new Set();
  var duplicate = false;
  // Only for statistics purpose
  var statistics = 0;
  for(var value in assignment.values) {
    statistics++;
    if(!set.add(value)) {
      duplicate = true;
      break;
    }
  }

  print("Duplicate: $duplicate");
  print("Performed in ${statistics} iteration(s) from $length possible");
}