C++ 如何根据一组规则/条件检查一组数据以进行分类?

C++ 如何根据一组规则/条件检查一组数据以进行分类?,c++,pattern-matching,C++,Pattern Matching,我有一组银行账户条目,存储在我定义的类bankAccountEntry的实例中。类bankAccountEntry具有数据成员 unsigned int year; unsigned int month; unsigned int day; std::string name; std::string accountNumberConsidered; std::string accountNumberContra; std::string code; double amount; std::st

我有一组银行账户条目,存储在我定义的类
bankAccountEntry
的实例中。类
bankAccountEntry
具有数据成员

unsigned int year;
unsigned int month;
unsigned int day;
std::string name;
std::string accountNumberConsidered;
std::string  accountNumberContra;
std::string code;
double amount;
std::string sortOfMutation;
std::string note;
我想对这些银行账户条目进行分类

例如,如果
std::string name
将包含子字符串
gasolinstation1
gasolinstation2
,则应将其分类在
汽油
下。为了实现这种分类,我可以通过语句检查数据成员

if (std::count(bae.name.begin(), bae.name.end(),"gasolineStation1")>0
    || 
    std::count(bae.name.begin(), bae.name.end(),"gasolineStation2")>0)
{
    bae.setCategory("gasoline");
}
对于所有银行账户条目的分类,我有一大组预定义的规则/条件,我想将其作为主程序的输入参数


有什么策略可以检查我的每个银行账户条目的规则/条件集,直到它找到一个匹配项?

如果,如果这里是big,则所有规则都是简单的名称类别映射,这可以相当干净地完成。如果规则不同。。。恶心

现在只看简单的案例

为了便于阅读和解释,请定义:

struct mapping
{
    std::string name;
    std::string category;
}
使用
std::pair
可能有战术优势。定义

std::vector<mapping> mappings;
这是蛮力。根据数据的外观,例如,如果数据严格遵循命名方案,则可以真正加快速度

如果规则更复杂,你会得到类似的结果:

struct mapping
{
    std::function<bool(const bankAccountEntry&)> rule;
    std::string category;
}
这是行不通的

差不多

bool gasolineStationRule(const bankAccountEntry& bae)
{
    return (bae.name.find("gasolineStation1")!= std::string::npos) ||
           (bae.name.find("gasolineStation2")!= std::string::npos);
}
mappings.push_back(mapping{&gasolineStationRule, "gasoline"})
将,但可以通过搜索一次“gasolineStation”,然后,如果找到“gasolineStation”,则测试其后面的字符的“1”或“2”来改进

如何将
规则
s引入向量将非常有趣。它可能需要大量的专门功能、一大群羔羊或一对树中的鹧鸪。问题中没有足够的具体说明来确定

它可能看起来像

bool gasolineStationRule(const bankAccountEntry& bae)
{
    return (bae.name.find("gasolineStation1")!= std::string::npos) ||
           (bae.name.find("gasolineStation2")!= std::string::npos);
}
mappings.push_back(mapping{&gasolineStationRule, "gasoline"})
或者通过向
映射添加构造函数

mapping(std::function<bool(const bankAccountEntry&)> newrule,
        std::string newcategory): rule(newrule), category(newcategory)
{

}
无论如何

bool bankAccountEntry::categorize()
{
    for (const mapping & kvp: mappings)
    {
        if (kvp.rule(*this))
        {
            setCategory(kvp.category);
            return true;
        }
    }
    return false;
}
同样,你对规则了解得越多,对规则的可预测性了解得越多,你就越能进行优化

作为
bankAccountEntry::categorize
的可能替代品


您能给我举一个
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
std::function
是日常普通函数的包装器,使其更容易传递。它还接受参数与或绑定的函数。这两种方法都有助于专门化更通用的函数,例如,您可以用绑定字符串替换硬编码的“gasolineStation1”,从而使用不同字符串的编辑中演示的函数。不过,这偏离了主题。你最好问一个新问题。
mappings.emplace_back(&gasolineStationRule, "gasoline")
bool bankAccountEntry::categorize()
{
    for (const mapping & kvp: mappings)
    {
        if (kvp.rule(*this))
        {
            setCategory(kvp.category);
            return true;
        }
    }
    return false;
}