我有一段这样的代码。
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
class A
{
public:
A(int iVal) : _val(iVal) {}
int getVal() const { return _val; }
private:
int _val;
};
class B
{
public:
B(int iNum) : _num(iNum) {}
int getNum() const { return _num; }
private:
int _num;
};
bool isInVecA(vector<A> vectorA, int iVal)
{
for(vector<A>::const_iterator it=vectorA.begin(); it != vectorA.end(); it++)
{
if(it->getVal() == iVal)
return true;
}
return false;
}
bool isInVecB(vector<B> vectorB, int iNum)
{
for(vector<B>::const_iterator it=vectorB.begin(); it != vectorB.end(); it++)
{
if(it->getNum() == iNum)
return true;
}
return false;
}
int main()
{
A arrayA[] = { A(1), A(2), A(3) };
vector<A> vectorA(arrayA, arrayA + sizeof(arrayA) / sizeof(A));
B arrayB[] = { B(3), B(4), B(5) };
vector<B> vectorB(arrayB, arrayB + sizeof(arrayB) / sizeof(B));
int key = 3;
if(isInVecA(vectorA, key) && isInVecB(vectorB, key))
cout << "Key " << key << " is in both vectors." << endl;
else
cout << "Key " << key << " is not in both vectors." << endl;
return 0;
}
我想做的只是创建一些东西来替换功能 isInVecA 和 isInVecB ,因为它们太相似了。假设我不能更改 A类和 B类。
非常感谢大家。 我是StackOverflow的新手。不知道在哪里发布我的朋友和我提出的解决方案。因此,我把它放在这里。
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>
#include <boost/bind.hpp>
using namespace std;
class A
{
public:
A(int iVal) : _val(iVal) {}
int getVal() const { return _val; }
private:
int _val;
};
class B
{
public:
B(int iNum) : _num(iNum) {}
int getNum() const { return _num; }
private:
int _num;
};
template<typename T>
bool isInVec(vector<T> vec, int (T::*func)() const, int iVal)
{
return find_if(vec.begin(), vec.end(), boost::bind(func, _1) == iVal) != vec.end();
}
int main()
{
A arrayA[] = { A(1), A(2), A(3) };
vector<A> vectorA(arrayA, arrayA + sizeof(arrayA) / sizeof(A));
B arrayB[] = { B(3), B(4), B(5) };
vector<B> vectorB(arrayB, arrayB + sizeof(arrayB) / sizeof(B));
int key = 3;
if(isInVec<A>(vectorA, &A::getVal, key) && isInVec<B>(vectorB, &B::getNum, key))
cout << "Key " << key << " is in both vectors." << endl;
else
cout << "Key " << key << " is not in both vectors." << endl;
return 0;
}
答案 0 :(得分:1)
您可以创建比较器并使用std::find_if
。
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
class A
{
public:
A(int iVal) : _val(iVal) {}
int getVal() const { return _val; }
private:
int _val;
};
class B
{
public:
B(int iNum) : _num(iNum) {}
int getNum() const { return _num; }
private:
int _num;
};
class cmpA
{
private:
int target;
public:
cmpA(int t) : target(t) {}
bool operator()(const A& a) const {
return a.getVal() == target;
}
};
class cmpB
{
private:
int target;
public:
cmpB(int t) : target(t) {}
bool operator()(const B& b) const {
return b.getNum() == target;
}
};
template<class T, class V>
bool isInVec(const vector<V>& vector, int iNum)
{
return find_if(vector.begin(), vector.end(), T(iNum)) != vector.end();
}
int main(void) {
A arrayA[] = { A(1), A(2), A(3) };
vector<A> vectorA(arrayA, arrayA + sizeof(arrayA) / sizeof(A));
B arrayB[] = { B(3), B(4), B(5) };
vector<B> vectorB(arrayB, arrayB + sizeof(arrayB) / sizeof(B));
int key = 3;
if(isInVec<cmpA>(vectorA, key) && isInVec<cmpB>(vectorB, key))
cout << "Key " << key << " is in both vectors." << endl;
else
cout << "Key " << key << " is not in both vectors." << endl;
return 0;
}
更新:代码较少的新代码,基于Adapter Design Pattern的想法:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
class A
{
public:
A(int iVal) : _val(iVal) {}
int getVal() const { return _val; }
private:
int _val;
};
class B
{
public:
B(int iNum) : _num(iNum) {}
int getNum() const { return _num; }
private:
int _num;
};
// dummy number getter
template<class T> int getNumber(const T& x) { return 0; }
// number getter for class A
template<> int getNumber(const A& x) { return x.getVal(); }
// number getter for class B
template<> int getNumber(const B& x) { return x.getNum(); }
// comparator using the number getter
template<class T>
class cmp
{
private:
int target;
public:
cmp(int t) : target(t) {}
bool operator()(const T& a) const { return getNumber<T>(a) == target; }
};
template<class T>
bool isInVec(const vector<T>& vector, int iNum)
{
return find_if(vector.begin(), vector.end(), cmp<T>(iNum)) != vector.end();
}
int main(void) {
A arrayA[] = { A(1), A(2), A(3) };
vector<A> vectorA(arrayA, arrayA + sizeof(arrayA) / sizeof(A));
B arrayB[] = { B(3), B(4), B(5) };
vector<B> vectorB(arrayB, arrayB + sizeof(arrayB) / sizeof(B));
int key = 3;
if(isInVec(vectorA, key) && isInVec(vectorB, key))
cout << "Key " << key << " is in both vectors." << endl;
else
cout << "Key " << key << " is not in both vectors." << endl;
return 0;
}
答案 1 :(得分:1)
class A
和class B
之间的界面不一致。首先通过引入从class C
继承的新类class B
来使界面通用。然后创建一个模板化的函数isInVec
进行比较。
class A
{
public:
A(int iVal) : _val(iVal) {}
int getVal() const { return _val; }
private:
int _val;
};
class B
{
public:
B(int iNum) : _num(iNum) {}
int getNum() const { return _num; }
private:
int _num;
};
class C: public B
{
public:
C(int iNum) : B(iNum){}
int getVal() const { return getNum(); }
};
template <typename T>
bool isInVec(std::vector<T> vect, int iVal)
{
for(std::vector<T>::const_iterator it=vect.begin(); it != vect.end(); it++)
{
if(it->getVal() == iVal)
return true;
}
return false;
}
int main()
{
A arrayA[] = { A(1), A(2), A(3) };
std::vector<A> vecA(arrayA, arrayA + sizeof(arrayA) / sizeof(A));
C arrayC[] = { C(3), C(4), C(5) };
std::vector<C> vecC(arrayC, arrayC + sizeof(arrayC) / sizeof(C));
int key = 3;
if(isInVec(vecA, key) && isInVec(vecC, key))
std::cout << "Key " << key << " is in both vectors." << std::endl;
else
std::cout << "Key " << key << " is not in both vectors." << std::endl;
return 0;
}
答案 2 :(得分:0)
我希望我可以回复你的问题作为评论,但我没有足够的声誉这样做。
IF 对矢量进行排序,然后使用&#34; std :: binary_search&#34;可能是您可以用来搜索矢量的最快算法,但请记住,矢量必须进行排序。
你必须包含&#34;算法&#34;文件,以便使用&#34; binary_search&#34;算法(我看到你已经完成了)。
&#34; binary_search&#34;可能会或可能不会为你工作,因为你告诉我们假设你不能改变任何一个类;如果是这种情况,你将无法实现&#34;小于&#34;的正确重载。运营商,如果需要这样的行动。
查看此链接以获取算法的完整说明:http://www.cplusplus.com/reference/algorithm/binary_search/
答案 3 :(得分:0)
#include <iostream>
#include <iterator>
#include <algorithm>
// class A and B unchanged, as requested
class A
{
public:
A(int iVal) : _val(iVal) {}
int getVal() const { return _val; }
private:
int _val;
};
class B
{
public:
B(int iNum) : _num(iNum) {}
int getNum() const { return _num; }
private:
int _num;
};
// new predicate to cover matching
struct matches
{
matches(int i) : _i(i) {};
bool operator()(const A& a) const {
return a.getVal() == _i;
}
bool operator()(const B& b) const {
return b.getNum() == _i;
}
int _i;
};
// convenience function to express the logic in a generic way
template<class Range>
bool contains(const Range& r, int key)
{
auto i = std::find_if(std::begin(r),
std::end(r),
matches(key));
return i != std::end(r);
}
// test
int main()
{
using namespace std;
A arrayA[] = { A(1), A(2), A(3) };
B arrayB[] = { B(3), B(4), B(5) };
int key = 3;
if (contains(arrayA, key) && contains(arrayB, key))
{
cout << "Key " << key << " is in both vectors." << endl;
}
else {
cout << "Key " << key << " is not in both vectors." << endl;
}
return 0;
}
答案 4 :(得分:0)
在某些时候,您必须区分A
和B
(或更准确地说getVal
和getNum
)。对于搜索算法(如前所述),std::find_if
可以与谓词Lambda一起使用:
#include <algorithm>
// ...
int target = 5;
auto found_A = std::find_if(vectorA.begin(), vectorA.end(),
[target](A const &a) -> bool { return a.getVal() == target; });
auto found_B = std::find_if(vectorB.begin(), vectorB.end(),
[target](B const &b) -> bool { return b.getNum() == target; });
if (found_A != vectorA.end() && found_B != vectorB.end())
{
// target in vA and vB
// with found_A and found_B being valid iterators to the elements
}