【问题标题】:look for only the first common element between two arrays仅查找两个数组之间的第一个公共元素
【发布时间】:2015-06-23 17:12:50
【问题描述】:

我有两个数组,分别是 a[] 和 b[]。我想搜索b中是否存在a的任何元素。请注意,我不想找到所有重复的事件,如果 a[] 中的任何一个元素存在于 b[] 中,我想报告它并在不检查 a[] 或 b[] 的其余部分的情况下中断

我对“break”的运作方式有些困惑。 'break' 可以跳出任何类型的循环 - for/while,但它只跳出它在代码中放置的“最内层循环”吗?

这是我的解决方案,请建议这种 O(n^2) 方法是否有更好的实现

#include <stdio.h>

int main(void)
{
 int a[] = {1,2,3,4,5,6};
 int b[] = {11,2,3,7,8,9,6,10,11};
 int i = 0, j = 0;
 int duplicate = 0;

 for(i=0;i<sizeof(a)/sizeof(int);i++)
 {
  for(j=0;j<sizeof(b)/sizeof(int);j++)
  {
   if(a[i] == b[j])
   {
    printf("Duplicates found for [%d]\n",a[i]);
    duplicate = 1;
    break;
   }
  }

  if(duplicate == 1)
  {
   break;
  }
 }

 return 0;
}

【问题讨论】:

  • 你能对数组进行排序吗?代替O(n^2),您可以在O(2.n.log n + n) 中进行搜索,这与O(n.log n) 相同
  • 如果您使用 O(nlogn) 排序(例如快速排序或归并排序)对每个数组进行排序,那么您可以在 O(n) 时间内遍历数组,从而产生 O(nlogn) 的整体复杂度.
  • 是的,break 会跳出它找到的最近的循环,无论是for 还是while
  • 另外...更大的缩进不会影响编译器的性能或执行速度,并且确实对程序员有帮助。

标签: c break duplicate-removal


【解决方案1】:

break 只中断使用它的最内层循环。如果你想避免丑陋的语法,那么你有多种解决方案:

  • 在您证明它相关之前忽略此优化
  • 将代码移到接受两个数组作为参数的函数中,这样您就可以直接从函数中return 而无需中断。
  • 调整索引ij 之后,您会发现重复项以使两个循环都正常返回
  • 使用goto 指令(在任何情况下都不可取)

复杂度低于 O(n^2) 的其他解决方案可能需要一些额外的数据结构,例如哈希集或数据排序。

【讨论】:

  • 我认为将代码重构为函数最有意义。
【解决方案2】:

breaks 通常会跳出 c 中最内层的循环。你用对了。

如果您只想报告重复,那么您可以将此代码放入一个函数中,每当发现重复时,您只需返回。该函数如下所示:

//Here a and b are pointers to array 
//n1 and n2 are number of elements in array a,b
chk_dup(int *a,int *b,int n1,,int n2){

for(i=0;i<n1;i++)
 {
  for(j=0;j<n2;j++)
  {
   if(a[i] == b[j])
   {
    printf("Duplicates found for [%d]\n",a[i]);
    //duplicate = 1;
    //break;
    return;
   }
  }
 }
}

你不能在这里使用 sizeof(a) 因为它只是一个指向数组的指针。同样适用于 sizeof(b)。

您可以通过使用快速排序(需要 O(nlgn))对数组进行排序,然后在 b 中对每个元素进行二分搜索,从而提高该算法的效率。

伪代码是这样的:

//Here a and b are pointers to sorted arrays 
//n1 and n2 are number of elements in array a,b
chk_dup(int *a,int *b,int n1,,int n2){

for(i=0;i<n1;i++)
 {
   //find a[i] in b using binary search.
   int found=binary_search(a[i],b);
   if(found){
     printf("Found Duplicate");
     return;
   }
 }
 printf("No duplicate found");
}

因此,整个算法的工作时间为 O(nlgn)。虽然您使用的算法可能需要 O(n^2)。

否则你的代码完全没问题,使用break是正确的

【讨论】:

    【解决方案3】:

    您可以使用goto,如此处所述How to break out of nested loops?,这是最后一个有效使用...

    也许使用xor有更好的解决方案,不确定是否可以减少

    虽然复杂...

    【讨论】:

      猜你喜欢
      • 2015-07-20
      • 1970-01-01
      • 2018-03-15
      • 1970-01-01
      • 2011-01-20
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      相关资源
      最近更新 更多