以下描述算法的名称是什么?
描述:
如何在给定模式中测试序列是否符合另一个序列?
例如:
The pattern: the number appears in the same order.
bool isOrderValid(vector<int>& mainVec, vector<int>& subVec) {
// how to implement this function?
}
test#1: isOrderValid({1, 2, 3, 4}, {2, 4}); // should return true
test#2: isOrderValid({1, 2, 3, 4}, {4, 2}); // should return false
说明:
测试#1:子序列为2,4;在主序列中,2出现在4之前,所以顺序正确。
测试#2:子序列是4,2;但是,在主序列中,4出现在2之后,因此顺序不正确。
注意:两个数组中可能都有重复的条目。例如:
isOrderValid({3, 6, 3, 1, 2, 3}, {3, 1, 3}); // should return true
答案 0 :(得分:2)
这可以非常简单地实现(我在这里使用函数对象):
class base_pattern_matcher{
public:
virtual bool operator()(const vector<int>& a , const vector<int>& b) = 0;
}
class in_order_pattern_matcher : public base_pattern_matcher{
public:
bool operator()(const vector<int>& a , const vector<int>& b){
vector<int>::iterator iter_a = a.begin() , iter_b = b.begin();
while(iter_b != b.end() && iter_a != a.end()){
if(*iter_b == *iter_a)
//we found an occurence in a that matches the searched element in b
//--> search for the next element
iter_b++;
//check if the next element matches the searched element
iter_a++;
}
//we have found all elements of b in the given order
return iter_b == b.end();
};
}
isOrderValid(const vector<int>& a , const vector<int>& b , const base_pattern_matcher& matcher){
return matcher(a , b);
}
答案 1 :(得分:1)
您可以为此编写标准库样式算法。此示例采用两个迭代器对并返回bool
:
#include <iostream>
#include <vector>
template <typename InIt1, typename InIt2>
bool is_subsequence(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2)
{
if (first2 == last2) {
return false; // sub empty (should this return true?)
}
for (; first1 != last1; ++first1) {
if (*first1 == *first2) {
if (++first2 == last2) {
return true; // sub exhausted
}
}
}
return false; // seq exhausted
}
int main()
{
std::vector<int> a = { 1, 2, 3, 4 }, b = { 2, 4 }, c = { 4, 2 };
std::vector<int> d = { 3, 6, 3, 1, 2, 3 }, e = { 3, 1, 3 };
std::cout << is_subsequence(a.begin(), a.end(), b.begin(), b.end()) << '\n';
std::cout << is_subsequence(a.begin(), a.end(), c.begin(), c.end()) << '\n';
std::cout << is_subsequence(d.begin(), d.end(), e.begin(), e.end()) << '\n';
}
如果您喜欢编写通用函数,可以使其更灵活,更易于使用:
#include <iostream>
#include <list>
#include <vector>
template <typename InIt1, typename InIt2, typename Compare = std::equal_to<>>
bool is_subsequence(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2, Compare cmp = Compare{})
{
if (first2 == last2) {
return false; // sub empty (should this return true?)
}
for (; first1 != last1; ++first1) {
if (cmp(*first1, *first2)) {
if (++first2 == last2) {
return true; // sub exhausted
}
}
}
return false; // seq exhausted
}
template <typename Seq, typename Sub, typename Compare = std::equal_to<>>
bool is_subsequence(const Seq &seq, const Sub &sub, Compare cmp = Compare{})
{
return is_subsequence(std::begin(seq), std::end(seq), std::begin(sub), std::end(sub), cmp);
}
int main()
{
std::vector<int> a = { 1, 2, 3, 4 }, b = { 2, 4 };
std::list<int> c = { 4, 2 };
std::vector<int> d = { 3, 6, 3, 1, 2, 3 };
int e[] = { 3, 1, 3 };
std::cout << is_subsequence(a, b) << '\n';
std::cout << is_subsequence(a, b, [](int lhs, int rhs) { return lhs == rhs; }) << '\n';
std::cout << is_subsequence(a, c) << '\n';
std::cout << is_subsequence(d, e) << '\n';
}