C ++使用第三个序列作为标准检查两个序列是否相等

C++ check if two sequences are equal using a 3rd sequence as criteria

我需要检查两个给定序列是否相等,但如果我发现不匹配的元素,我需要检查第三个序列(与其他两个序列大小相同)是否可以忽略。

我知道我可以写一个简单的算法来解决这个问题,但我想知道是否有任何类似 C++ 的风格来解决这个问题,使用标准算法。

示例:

A = [1, 2, 3, 4, 5, 6]
B = [1, 2, 3, A, 5, 6]
M = [true, true, true, false, true, true]
N = [true, true, true, true, true, true]

bool equal1 = the_equal(begin_A, end_A, begin_B, begin_M); // Should return true, even if '4' is different from 'A' since in the same position of the found mismatch, in the M sequence, we have a false that indicates that position should be ignored.

bool equal2 = the_equal(begin_A, end_A, begin_B, begin_N); // Should return false, since '4' is different from 'A' and we have a true in sequence N for that position.

这可以通过类似的方式解决:

template<I1, I2, I3> // iterators
bool the_equal(I1 first1, I1 last1, I2 first2, I3 first3) {
  while (first1 != last1) {
    if (*first1 != *first2 && *first3 != false)
      return false;
    ++first1; ++first2; ++first3;
  }

  return true;
}

编辑:由于工具链的限制,我忘了说我需要在 c++98 中解决这个问题:(

虽然std::equal接近了,但不清楚是否可以直接使用。我认为您的代码非常好。我可能会将其重写为

template<I1, I2, I3> // iterators
bool equal_with_mask(I1 first1, I1 last1, I2 first2, I3 first3) {
  for (; first1 != last1; ++first1, ++first2, ++first3) {
    if (*first3 && (*first1 != *first2)) {
      return false;
    }
  }
  return true;
}

如果(不)相等比较很重,那么首先检查掩码可能会很好。

小知识:第三个序列 (first3) 就像在某些硬件设备中使用的掩码,例如三元内容可寻址存储器 (TCAM)。

您可以创建一个(可变的)仿函数:

template <typename IT>
struct CmpWithMask
{
    CmpWithMask(IT it) : it(it) {}

    template <typename LHS, typename RHS>
    bool operator () (const LHS& lhs, const RHS& rhs) {
        return !*it++ || lhs == rhs;
    }
    IT it;
};

template <typename IT>
CmpWithMask<IT> MakeCmpWithMask(IT it) { return CmpWithMask<IT>{it}; }

然后,使用std::equal:

std::cout << std::equal(A.begin(), A.end(),
                        B.begin(),
                        MakeCmpWithMask(M.begin())) << std::endl;
std::cout << std::equal(A.begin(), A.end(),
                        B.begin(),
                        MakeCmpWithMask(N.begin())) << std::endl;

我也觉得你的代码很好。您可以使用标准函数之一,但恕我直言,并不总是建议这样做,因为它会降低代码的可读性。最好的解决方案是您可以阅读的解决方案。但是,这里有一个解决方案(许多可能的实现之一)使用 std::mismatch :

template<typename I1, typename I2, typename I3> // iterators
bool the_equal2(I1 first1, I1 last1, I2 first2, I3 first3) {
  auto p = std::mismatch(first1, last1, first2);
  if(p.first != last1)
    return (!first3[p.first - first1] ? true : the_equal2(p.first+1, last1, p.second+1, first3));

  return false;
}

请参阅 here 实际操作,并注意,未检查错误...

但是它看起来比 发布的例子更好吗?使用递归和 auto p,如果您不知道什么不匹配 returns(std::pair<I1, I2>),您甚至必须查找 p 可能是什么类型?您甚至可以通过使用一些 iterator_traits 或奇特的 find_if/equal/mismatch 组合来改进它,以摆脱递归并使其更加不可读。