【问题标题】:Compare two arrays and create new array with equal elements in C比较两个数组并在 C 中创建具有相等元素的新数组
【发布时间】:2017-01-24 13:58:51
【问题描述】:

问题是检查两个数组是否有相同的整数值并将匹配的值放入一个新数组中。

假设我有两个数组

a[n] = {2,5,2,7,8,4,2}
b[m] = {1,2,6,2,7,9,4,2,5,7,3}

每个数组可以是不同的大小。

我需要检查数组是否有匹配的元素并将它们放入一个新数组中。这种情况下的结果应该是:

array[] = {2,2,2,5,7,4}

我需要在 O(n.log(n) + m.log(m)) 中完成。

我知道有一种方法可以进行归并排序或将其中一个数组放入哈希数组中,但我真的不知道如何实现它。

非常感谢您的帮助,谢谢!!!

【问题讨论】:

  • 为什么不遍历它?
  • 我真的没有做对任何事情......只是在想如何开始这个问题:\
  • 因为它需要 nlogn + mlogm @OscarLundberg
  • 为什么结果是2,2,2,5,7,4?无论您如何处理,该订单似乎都没有任何意义
  • 在自己动手之前永远不要问,否则你什么都学不到。

标签: c arrays algorithm


【解决方案1】:

正如您已经发现可以使用合并排序(实现它超出了此答案的范围,我想您可以在 wikipedia 上找到解决方案或在 Stack Overflow 上搜索)以便您可以得到 nlogn + mlogm复杂性假设n 是第一个数组的大小,m 是另一个数组的大小。

让我们调用第一个数组a(大小为n)和第二个数组b(大小为m)。首先对这些数组进行排序(合并排序会给我们nlogn + mlogm 复杂度)。现在我们有了:

a[n] // {2,2,2,4,5,7,8}b[n] // {1,2,2,2,3,4,5,6,7,7,9}

假设n <= m 我们可以简单地迭代模拟比较对应的值:

但首先让我们分配数组int c[n]; 来存储结果(如果需要,您可以打印到控制台而不是存储)。现在循环本身:

 int k = 0;  // store the new size of c array!
 for (int i = 0, j = 0; i < n && j < m; )
 {
     if (a[i] == b[j])
     {
         // match found, store it
         c[k] = a[i];
         ++i; ++j; ++k;
     }
     else if (a[i] > b[j])
     {
         // current value in a is leading, go to next in b
         ++j;
     }
     else
     {
         // the last possibility is a[i] < b[j] - b is leading
         ++i;
     }
}

注意:循环本身最坏的情况是n+m 复杂度(记住n &lt;= m 假设),它低于排序,因此总体复杂度为nlogn + mlogm。现在您可以迭代 c 数组(它的大小实际上是我们分配的 n,但其中的元素数量是 k)并使用这些数字做您需要的事情。

【讨论】:

    【解决方案2】:

    从您解释它的方式来看,这样做的方法是遍历较短的数组并根据较长的数组检查它。让我们假设 A 是较短的数组,B 是较长的数组。创建结果数组 C。

    1. 循环遍历 A 中的每个元素,称其为 I

    2. 如果在 B 中找到 I,将其从 B 中移除并放入 C,跳出测试循环。

    3. 现在转到 A 中的下一个元素。

    这意味着如果一个数 I 在 A 中出现两次,在 B 中出现 3 次,那么 I 只会在 C 中出现两次。一旦你完成,那么在两个数组中找到的每个数字都会在 C 中出现的次数它实际上出现在两者中。

    我小心地没有输入建议的代码,因为您的问题是关于您可以使用的方法。你应该自己弄清楚代码。

    【讨论】:

      【解决方案3】:

      我倾向于采取以下方法:

      1) 排序数组 B。有许多已发布的排序算法可以做到这一点,以及各种通用库中的几种实现。

      2) 遍历数组 A 并为每个元素在数组 B 上执行二进制搜索(或其他合适的算法)以进行匹配。如果找到匹配项,则从数组 B 中删除元素(以避免将来匹配)并将其添加到输出数组中。

      【讨论】:

      • 这个算法的复杂度是O((n+m).log(m))。对两个数组进行排序会产生预期的复杂性并更准确地处理重复项。
      • 谢谢,chqrlie。我从来没有学过如何计算算法的阶数。我猜对两个数组进行排序会降低匹配的顺序,因为您可以记住以前的位置并且只能向前搜索。
      • 对两个数组进行排序后,匹配可以在线性时间内完成,不会增加复杂度。有关详细信息,请参阅 Yuriy Ivaskevych 的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      相关资源
      最近更新 更多