這裏是要求:比較具有不同類型值的兩組
我有一個屬性列表。每個屬性都有一個int類型的標籤和一個以下類型的值:(bool,char,string,int,long)。 一些樣本性質:
標籤:1,值: 「一些字符串」
標籤:14,值:真
標籤:20,值:123
還有一個列表的規則。每條規則就像一個屬性,加上以下其中一個運算符:(<,>,< =,> =,==,!=,startsWith)。 startsWith運算符用於檢查一個字符串是否以另一個字符串開頭。
一些樣本規則:
標籤:1,價值: 「你好」,運營商:==
標籤:14,值:真,符:==
每個列表的規則稱爲Criteria
並用於驗證屬性列表。如果僅滿足條件的所有規則,則條件驗證屬性列表。例如,上面的兩條規則構成了一個標準。此條件不驗證上述屬性列表,因爲第1條規則強制tag(1)的值等於(==)爲「hello」,而不是。
以下標準:
標籤:1,值: 「一些字符串」,操作者:==
標籤:20,值:100,操作者:>
標籤:20,值: 120,操作者:<
不驗證上述性質也是如此,因爲雖然前兩個規則都滿足時,最後一個規則,這迫使標籤(20)的值小於120是不正確的。因此整個標準不會驗證屬性。
這裏是驗證爲真一個標準:
標籤:1,價值: 「一些」,運營商:startsWith
標籤:14,值:false,運算符:!=
標籤:20 ,值:123,操作者:> =
標籤:20,值:100,操作者:>
到目前爲止我已經提出了下面的代碼。但我卡在StartsWith
運營商的執行。也許我應該選擇一種完全不同的方法來解決這個問題。任何意見和幫助將不勝感激!
#include <string>
#include <iostream>
#include <set>
#include <algorithm>
#include <tr1/memory>
using namespace std;
/////////////////// Property Class //////////////////////
class Property
{
public:
enum Operator
{
EQ, // ==
NEQ, // !=
GT, // >
GTE, // >=
LT, // <
LTE, // <=
SW, // Starts With
} mOperator;
Property() {};
Property(const int tag, Operator op)
: mTag(tag), mOperator(op) {}
virtual ~Property() {}
virtual void* GetValue() = 0;
virtual bool IsEqual(void* value) = 0;
virtual bool Compare(void* value, Property::Operator op) = 0;
virtual void Print() = 0;
int mTag;
bool operator<(const Property &property) const
{
return mTag < property.mTag;
}
};
struct PropertyPtrComp
{
bool operator()(const std::tr1::shared_ptr<Property> lhs, const std::tr1::shared_ptr<Property> rhs) const
{
return lhs->mTag < rhs->mTag;
}
};
/////////////////// TypedProperty Class /////////////////
template< typename T >
class TypedProperty : public Property
{
public:
TypedProperty (const int tag, const T& value, Property::Operator op)
: Property(tag, op), mValue(value) {}
void* GetValue()
{
return &mValue;
}
bool IsEqual(void* value)
{
return *((T*)value) == mValue;
}
bool Compare(void* value, Property::Operator op)
{
// cout << "comparing " << *((T*)value) << " with " << mValue << endl;
switch (op)
{
case Property::EQ:
return *((T*)value) == mValue;
case Property::NEQ:
return *((T*)value) != mValue;
case Property::GT:
return mValue > *((T*)value) ;
case Property::LT:
return mValue < *((T*)value) ;
case Property::SW:
{
if (typeid((T*)value) == typeid(string*))
{
// dont know what to do!
//return ((string)mValue).compare(0, ((string*)value)->length(), (string)(*((string*)value)));
}
}
default:
return *((T*)value) == mValue;
}
}
void Print()
{
cout << "Tag: " << mTag << ", Value: " << mValue << endl;
}
T mValue;
};
/////////////////////////////////////////////////////////
typedef std::tr1::shared_ptr<Property> PropertyPtr;
/////////////////// PropertyList Class /////////////////
class PropertyList
{
public:
PropertyList() {};
virtual ~PropertyList() {};
template <class T>
void Add(int tag, T value, Property::Operator op = Property::EQ)
{
PropertyPtr ptr(new TypedProperty<T>(tag, value, op));
mProperties.insert(ptr);
}
void Print()
{
cout << "-----------" << endl;
for (set<PropertyPtr>::iterator itr = mProperties.begin(); itr != mProperties.end(); itr++)
{
(*itr)->Print();
}
}
set<PropertyPtr, PropertyPtrComp> mProperties;
};
//////////////////// Check Subset ///////////////////////
/*
* Checks if subset is included in superset
*/
bool CheckSubset(set<PropertyPtr, PropertyPtrComp> &superset,
set<PropertyPtr, PropertyPtrComp> &subset)
{
if (subset.size() > superset.size() || subset.empty()) return false;
typename set<PropertyPtr>::iterator litr = superset.begin();
for (typename set<PropertyPtr>::iterator ritr = subset.begin(); ritr != subset.end();)
{
while (litr != superset.end())
{
PropertyPtr lProp = (PropertyPtr)*litr;
PropertyPtr rProp = (PropertyPtr)*ritr;
if (lProp->mTag == rProp->mTag)
{
if (lProp->Compare(rProp->GetValue(), rProp->mOperator))
{
litr++;
break;
}
return false;
}
else
{
litr++;
}
}
ritr++;
if (litr == superset.end() && ritr != subset.end()) return false;
}
return true;
}
int main()
{
PropertyList properties;
string s = "bye";
properties.Add(1, "hello");
properties.Add(2, 12);
properties.Add(3, 34);
properties.Add(4, "bye");
properties.Print();
PropertyList ruleSet1;
ruleSet1.Add(2, 12, Property::EQ);
ruleSet1.Add(4, "bye", Property::EQ);
ruleSet1.Print();
if(CheckSubset(properties.mProperties, ruleSet1.mProperties))
cout << "RuleSet1 verified!" << endl; // <<<< should be printed
else
cout << "RuleSet1 NOT verified!" << endl;
PropertyList ruleSet2;
string hel = "hel";
ruleSet2.Add(1, hel, Property::SW);
ruleSet2.Add(2, 13, Property::NEQ);
ruleSet2.Print();
if (CheckSubset(properties.mProperties, ruleSet2.mProperties))
cout << "RuleSet2 verified!" << endl; // <<<< should be printed
else
cout << "RuleSet2 NOT verified!" << endl;
}
我認爲代碼牆讓代碼評論SE更有意義。 –
我在這裏沒有看到問題。標題中可能藏有一個,但我不確定它是什麼。但是,答案似乎是,您希望提供比較運算符或哈希函數,並使用它來提供集合運算。 – eh9