【问题标题】:checking if an array is contained in another, in reverse order, at least twice检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
【发布时间】:2020-06-28 18:00:33
【问题描述】:

我编写了一个 C++ 函数 hasMirrorTwice,它将两个整数数组 arr1 和 arr2 及其长度作为参数,并检查 arr1 是否包含 arr2 的所有元素以相反的顺序至少两次。下面是函数。我想知道是否有办法简化它?

bool hasMirrorTwice(int a1[], int a2[], int size1, int size2) {
  int num_reps = 0;
  bool contains = false;
  for (int i = 0; i < size1; ++i) {
    contains = false;
    if (a1[i] == a2[size2 - 1]) {
      contains = true;
      for (int k = size2 - 2; k >= 0; --k) {
        if (i + size2 - 1 - k >= size1 || a2[k] != a1[i + size2 - 1 - k]) {
          contains = false;
          break;
        }
      }
    }
    if (contains) {
      ++num_reps;
      i += size2 - 2;
    }
    if (num_reps >= 2) {
      return true;
    }
  }

  return false;
}

在下面的main函数中,输出应该为真。

#include <iostream>
int main() {
  int a4[] = {1,2,3,2,3,2};
  int a5[] = {2,3,2};
  std::cout << std::boolalpha << hasMirrorTwice(a4, a5, 6, 3) 
            << std::endl;
}

【问题讨论】:

  • 如果您想获得更好的性能,请尝试实现Knuth–Morris–Pratt algorithm,或者如果您想编写更少的代码,请在执行std::reverse 之后直接使用std::find
  • 您对该函数的调用实际上并未编译。另外,你为什么不使用std::vector 而不是数组?
  • @cigien 抱歉。我修好了。

标签: c++ arrays for-loop


【解决方案1】:

您可以使用标准库std::search 算法和反向迭代器。例如:

bool hasMirrorTwice(const int *a1, const int *a2, int size1, int size2)
{
    using ritr = std::reverse_iterator<const int *>;

    // first match
    auto itr = std::search(a1, a1 + size1, ritr(a2 + size2), ritr(a2));
    if (itr == a1 + size1) {
        return false; // no match
    }

    // second match (start 1 position after previous match)
    itr = std::search(itr + 1, a1 + size1, ritr(a2 + size2), ritr(a2));
    return itr != a1 + size1;
}

C++17 添加了可用于std::search 的附加搜索算法。在前面的例子中添加Boyer-Moore搜索算法是一个小的修改。

bool hasMirrorTwice(const int *a1, const int *a2, int size1, int size2)
{
    using ritr = std::reverse_iterator<const int *>;

    auto searcher = std::boyer_moore_searcher(ritr(a2 + size2), ritr(a2));

    // first match
    auto itr = std::search(a1, a1 + size1, searcher);
    if (itr == a1 + size1) {
        return false; // no match
    }

    // second match (start 1 position after previous match)
    itr = std::search(itr + 1, a1 + size1, searcher);
    return itr != a1 + size1;
}

【讨论】:

    【解决方案2】:

    好吧,如果是整数或字符,您可以将数组视为字符串,并使用 Rabin-Karp 算法检查反向目标字符串是否在被比较的字符串中。复杂度运行时间通常小于 $O(|T||P|)$ 与 |T|是第一个目标字符串的长度和 |P|被比较的字符串的长度。

    【讨论】:

      猜你喜欢
      • 2019-07-22
      • 2018-08-30
      • 1970-01-01
      • 2015-10-28
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      相关资源
      最近更新 更多