从结构向量中查找向量的子序列

时间:2017-10-30 23:42:57

标签: c++ vector struct

我试图从较大的矢量中找到矢量的子序列。

这是我的完整代码。

#include <iostream>
#include <vector>

using namespace std;

struct Elem {

    bool isString;
    float f;
    string s;
};

void getFounds(vector<Elem> &src, vector<Elem> &dst, vector<size_t> &founds)
{
    //what should be in here?
}

int main(int argc, const char * argv[]) {

    vector<Elem> elems1 = {{false, 1.f, ""}, {false, 2.f, ""}, {true, 0.f, "foo"},
                           {false, 1.f, ""}, {false, 2.f, ""}, {true, 0.f, "foo"}}; //the source vector
    vector<Elem> elems2 = {{false, 2.f, ""}, {true, 0.f, "foo"}}; //the subsequence to find
    vector<size_t> founds; //positions found

    getFounds(elems1, elems2, founds);

    for (size_t i=0; i<founds.size(); ++i)
        cout << founds[i] << endl; // should print 1, 4

    return 0;
}

我可以使用std::search执行此操作,如果我将其用于单个类型的向量,但如果我将其用于结构的向量,则会显示错误

  

&#34;二进制表达式的操作数无效(&#39; const Elem&#39;和&#39; const   ELEM&#39;)&#34;

在这种情况下使用std::search真的不可能吗? 在代码中实现getFounds()的好方法是什么?

编辑:我可以通过创建operator函数并使用std::search

来使其工作
bool operator==(Elem const& a, Elem const& b)
{
    return a.isString == b.isString && a.f == b.f && a.s == b.s;
}

void getFounds(vector<Elem> &src, vector<Elem> &dst, vector<size_t> &founds)
{
    for (size_t i=0; i<src.size(); ++i) {

        auto it = search(src.begin()+i, src.end(), dst.begin(), dst.end());

        if (it != src.end()) {

            size_t pos = distance(src.begin(), it);
            founds.push_back(pos);
            i += pos;
        }
    }
}

但是,如果有人能给我一些建议让代码更简单,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

  

在这种情况下使用std::search真的不可能吗?

不,您只需要在operator==中实施struct功能即可。您也可以实现operator!=,例如:

struct Elem
{
    bool isString;
    float f;
    std::string s;

    bool operator==(const Elem& other) const {
        return (this->isString == other.isString &&
                this->f == other.f &&
                this->s == other.s);
    }

    bool operator!=(const Elem& other) const {
        return !(*this == other);
    }
};
  

在代码中实现getFounds()的好方法是什么? ...建议使其更简单。

更简单是相对的,特别是因为你已经在使用标准库来实现你想要的东西;但是,您也可以像这样实现getFounds函数:

void getFounds(const std::vector<Elem>& src, const std::vector<Elem>& sub, std::vector<size_t>& founds)
{
    size_t count = 0, tot = 0;
    auto beg = sub.begin();
    for (auto look = src.begin(); look != src.end();) {
        if (*look != *beg) { ++look; ++count; continue; }
        for (tot = 0; beg != sub.end(); ++beg, ++look, ++tot) {
            if (look == src.end()) { break; }
            if (*look != *beg) { break; }
        }
        if (tot == sub.size()) { founds.push_back(count); }
        count += tot;
        beg = sub.begin();
    }
}

我不知道这对你的需求是否“更简单”,因为它基本上是std::search算法所做的(如果元素不匹配则循环和检查并中断等),它只是做到这一点的“另一种”方式。

希望有所帮助。

答案 1 :(得分:1)

覆盖==并遍历两个数组以寻找匹配:

bool operator==(Elem const &el1, Elem const &el2)
{
    return 
        el1.isString == el2.isString 
        && 
        el1.f == el2.f 
        && 
        el1.s == el2.s;
}

void getFounds(std::vector<Elem> const &src, std::vector<Elem> const &dst, std::vector<size_t> &founds)
{
    for (size_t i = 0; i < src.size(); ++i)
        for (size_t j = 0; j < dst.size(); ++j)
            if (src[i] == dst[j])
                founds.push_back(i);
}

然而,这将找到每个索引。例如,您的示例将打印1 2 4 5.如果您想在第一次查找后中止,则需要为其添加一些额外的逻辑。