ここで大きければ、すべてのルールが単純な名前 - カテゴリマッピングであり、これはかなりきれいに行うことができます。ルールが変わったら...ヤク。
今の簡単なケースでのみ見て、読書や説明を容易にするため
定義:
struct mapping
{
std::string name;
std::string category;
}
代わりstd::pair<std::string,std::string>
を使用して、戦術的な利点があるかもしれません。そして定義する
std::vector<mapping> mappings;
ルールファイルからmappings
に名前カテゴリのペアを読みます。ルールの内容がわからないため、これに関するアドバイスはできません。これが完了したら
bool bankAccountEntry::categorize()
{
for (const mapping & kvp: mappings)
{
if (name.find(kvp.name) != std::string::npos)
{
setCategory(kvp.category);
return true;
}
}
return false;
}
これはブルートフォースです。データがどのように見えるかによって、たとえば名前付けスキームに厳密に従っている場合など、実際にはこれをスピードアップできます。
ルールが複雑であれば、あなたはより多くのようなもので羽目になる:
struct mapping
{
std::function<bool(const bankAccountEntry&)> rule;
std::string category;
}
と
std::vector<mapping> mappings;
各mapping::rule
はbankAccountEntry
をbankAccountEntry
を取り、か否かを判断する機能ですルールに適合します。たとえば、
bool gasolineStationRule(const bankAccountEntry& bae)
{
return std::count(bae.name.begin(), bae.name.end(),"gasolineStation1")>0 ||
std::count(bae.name.begin(), bae.name.end(),"gasolineStation2")>0;
}
because std::count
doesn't work like thatは動作しません。
何か
bool gasolineStationRule(const bankAccountEntry& bae)
{
return (bae.name.find("gasolineStation1")!= std::string::npos) ||
(bae.name.find("gasolineStation2")!= std::string::npos);
}
がしますが、「1」または「2」のためにそれの後に文字をテストし、「gasolineStation」が発見された場合は、「gasolineStation」のために、一度検索してによってに改善することができるように。
ベクターにrule
をどうやって入れるのかはかなり楽しいでしょう。特殊な機能の大規模なプール、Lambdasの軍隊、またはペアツリーの子嚢を必要とする可能性があります。質問には必ずしも十分とは言えません。
それはおそらく
mappings.push_back(mapping{&gasolineStationRule, "gasoline"})
またはmapping
mapping(std::function<bool(const bankAccountEntry&)> newrule,
std::string newcategory): rule(newrule), category(newcategory)
{
}
にコンストラクタを追加することによって、あなたはとにかく
mappings.emplace_back(&gasolineStationRule, "gasoline")
から小さなパフォーマンスの向上を得ることができようになります...
bool bankAccountEntry::categorize()
{
for (const mapping & kvp: mappings)
{
if (kvp.rule(*this))
{
setCategory(kvp.category);
return true;
}
}
return false;
}
さらに、ルールについて知っているほど、予測可能なほど、最適化できるほどです。
Also look at std::find_if
bankAccountEntry::categorize
の腸のための可能な置き換えとして。
Documentation on std::function
.
あなたは私の 'のstd :: function'の定義の例をお願いできますか?私が言及したルールのために 'std :: function'を定義することができますか?したがって、 'if(std :: count(bae.name.begin()、bae.name.end()、" gasolineStation1 ")> 0 || std :: count(bae.name.begin()、bae。 name.end()、 "gasolineStation2")> 0) 'となります。 – Adriaan
'std :: function'は日常的な普通の関数を包み込み、渡しやすくします。また、['std :: bind'](http://en.cppreference.com/w/cpp/utility/functional/bind)または[ラムダ式](http://en.cppreference .com/w/cpp/language/lambda)。いずれの場合でも、ハードコーディングされた "gasolineStation1"をバインドされた文字列に置き換えるなど、より一般的な機能を特化するのに役立ちます。しかし、それは話題になっています。あなたは新しい質問をするのが良いです。 – user4581301