Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 嵌套循环复杂性_Algorithm_List_Loops_Time Complexity - Fatal编程技术网

Algorithm 嵌套循环复杂性

Algorithm 嵌套循环复杂性,algorithm,list,loops,time-complexity,Algorithm,List,Loops,Time Complexity,我有几个大小不同的列表,列表的每个索引都包含一个键和一个对象:list1.add('key',obj) 列表都已排序 我的目标是遍历列表,并使用键将列表2、3、4或n中的一个或多个项目与主列表中的一个项目进行匹配 目前,我做了如下工作: for i to list1 size for j to list2 size if list1[i] = list2[j] do stuff 当我循环时,我正在使用布尔值快速退出,使用if current!=上一次检查时,我正在从获

我有几个大小不同的列表,列表的每个索引都包含一个键和一个对象:list1.add('key',obj)

列表都已排序

我的目标是遍历列表,并使用键将列表2、3、4或n中的一个或多个项目与主列表中的一个项目进行匹配

目前,我做了如下工作:

for i to list1 size
   for j to list2 size
   if list1[i] = list2[j]
      do stuff 
当我循环时,我正在使用布尔值快速退出,使用if current!=上一次检查时,我正在从获取对象的列表中删除该对象

它的工作很好,但我现在有另一个列表,我需要匹配和可能的另一个n名单之后。名单大小不一

我可以看到的两个选项是,在内部列表发生变化的地方,重复上述代码段数次——我不喜欢这种方法

另一个选项是扩展上述内容,完成一个内部循环后,移动到下一个:

  for i to list1 size
       for j to list2 size
       if list1[i] = list2[j]
          do stuff 
       for k to list2 size
       if list1[i] = list2[k]
          do stuff 
我认为我认为第二种方法更有效是正确的,但是我不确定。还有,还有更好的办法吗


感谢您的建议/帮助。

如果列表都已排序,那么您只需在每个列表中迭代一次;在主列表的每次迭代中,迭代次列表(从先前保存的索引开始,初始化为0),直到找到值大于主列表当前值的索引,保存此索引,然后继续下一次次次列表

Array<Integer> indices = new Array(n-1); // indices for every list except list1
for(int i = 0; i < indices.size; i++) {
  indices[i] = 0;
}

for(int i = 0; i < list1.size; i++) {
  Value curVal = list1[i];
  while(indices[0] < list2.size && list2[indices[0]] <= curVal) {
    if(list2[indices[0]] == curVal) {
      // do stuff on list2[indices[0]]
    }
    indices[0]++;
  }
  while(indices[1] < list3.size && list3[indices[1]] < curVal) {
    if(list3[indices[1]] == curVal) {
      // do stuff on list3[indices[1]]
    }
    indices[1]++;
  }
  // etc
}
这是时间复杂度O(n),其中n是所有列表长度的总和



编辑:如果很难通过
比较键,则它们都具有相同的时间复杂度。第一个选项是
O(i*j)+O(i*k)
,第二个选项是
O(i*(j+k))
@Barmar:谢谢。那么复杂性是n^2吗?我认为在某些情况下,它可能会不断改进,但复杂性分析不是我的强项:)这个问题似乎离题了,因为cs.stackexchange.com会是解决此类问题的更好地方。@Barmar:谢谢,我没有意识到它会被认为离题。我现在就移动它,除非你想根据评论发布答案嗨,我只是想实现你的解决方案。不幸的是,我没有访问迭代器的权限;德尔福旧版本的乐趣。在何处执行“&&list2[index[0]]@SteveGreen键的顺序如何?根据您的示例,它看起来可能是“如果key1的字母前缀小于key2的字母前缀,则key1list2[索引[0]]@SteveGreen如果编写
isLessThan
方法不可行,那么如果您可以访问
集合
数据结构(这可以实现为带有空值的
映射
字典
),那么您可以将所有List1键添加到集合中,然后遍历所有其他列表,测试集合成员资格
list2[index[0]]@SteveGreen提供了一个很好的哈希函数的Delphi实现。分配一个名为
set
的数组,该数组大于List1.size,通常大于25%到100%,具体取决于内存限制(数组越大,冲突越少)。此数组包含字符串的链接列表。将字符串添加到数组时,计算
int key=hash(string)modulo set.size
,并将该字符串附加到
set[key]
处的链接列表中。查找也会执行相同的操作-计算关键点,然后遍历链表以获得精确的结果match@SteveGreen使用链表处理冲突是一种“封闭寻址”方案;“开放寻址”方案是一种在检测到冲突时将字符串添加到相邻数组元素的方案(对于“相邻”的某些定义,不同的开放寻址方案使用不同的探测技术)。有关特定的开放寻址方案,请参阅Wikipedia上的文章。
public class ListIterator {
  int index = 0;
  List<Value> list;
  Value curVal() {
    return list[index];
  }
  boolean hasNext() {
    return (index < list.size);
  }
}

List<ListIterator> iterators;
for(int i = 0; i < list1.size; i++) {
  Value curVal = list1[i];
  for(int j = 0; j < iterators.size; j++) {
    ListIterator iterator = iterators[j];
    while(iterator.hasNext() && iterator.curVal() <= curVal) {
      if(iterator.curVal() == curVal) {
        // do something with iterator.curVal()
      }
      iterator.index++;
    }
  }
}
Set<String> set = new Set(List1);
Array<List> lists = new Array();
// add lists to Array<List>

for(int i = 0; i < lists.size; i++) {
  List currentList = lists[i];
  for(int j = 0; j < currentList.size; j++) {
    if(set.contains(currentList[j]) {
      // do something
    }
  }
}