我试图从较大的矢量中找到矢量的子序列。
这是我的完整代码。
#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;
}
}
}
但是,如果有人能给我一些建议让代码更简单,我将不胜感激。
答案 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.如果您想在第一次查找后中止,则需要为其添加一些额外的逻辑。