簡體   English   中英

如何測試序列是否符合給定模式中的另一個序列?

[英]How to test if a sequence is conform to another sequence in a given pattern?

以下描述算法的名稱是什么?

描述:

如何在給定模式中測試序列是否符合另一個序列?

例如:

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

這可以非常簡單地實現(我在這里使用函數對象):

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);
}

您可以為此編寫標准庫樣式算法。 這個例子需要兩個迭代器對並返回一個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';
}

在ideone.com上執行

如果您喜歡編寫通用函數,可以使其更靈活,更易於使用:

#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';
}

在ideone.com上執行

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM