首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何根据一组分类规则/条件检查一组数据?

如何根据一组分类规则/条件检查一组数据?
EN

Stack Overflow用户
提问于 2017-01-31 02:30:27
回答 1查看 51关注 0票数 1

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

代码语言:javascript
运行
复制
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将包含子字符串gasolineStation1gasolineStation2,则应将其归类为gasoline。为了实现这种分类,例如,我可以通过语句检查数据成员

代码语言:javascript
运行
复制
if (std::count(bae.name.begin(), bae.name.end(),"gasolineStation1")>0
    || 
    std::count(bae.name.begin(), bae.name.end(),"gasolineStation2")>0)
{
    bae.setCategory("gasoline");
}

为了对我的所有银行帐户条目进行分类,我有一大组这样的预定义规则/条件,我希望将它们作为输入参数提供给主程序。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-31 03:38:36

如果,在这里,所有的规则都是简单的名称-类别映射,这可以相当干净地完成。如果规则不同..。糟透了。

现在只看简单的例子,

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

代码语言:javascript
运行
复制
struct mapping
{
    std::string name;
    std::string category;
}

相反,使用std::pair<std::string,std::string>可能有战术上的优势。并定义

代码语言:javascript
运行
复制
std::vector<mapping> mappings;

将规则文件中的名称-类别对读取到mappings中。不能给出任何建议,因为我们不知道规则是什么样子的。一旦完成此操作

代码语言:javascript
运行
复制
bool bankAccountEntry::categorize()
{
    for (const mapping & kvp: mappings)
    {
        if (name.find(kvp.name) != std::string::npos)
        {
            setCategory(kvp.category);
            return true;
        }
    }
    return false;
}

这是蛮力。根据您的数据的外观,例如,如果它严格遵循命名方案,您可以真正加快速度。

如果规则更复杂,你会得到更像这样的结果:

代码语言:javascript
运行
复制
struct mapping
{
    std::function<bool(const bankAccountEntry&)> rule;
    std::string category;
}

代码语言:javascript
运行
复制
std::vector<mapping> mappings;

每个mapping::rule都是一个接受bankAccountEntry并决定bankAccountEntry是否符合规则的函数。例如:

代码语言:javascript
运行
复制
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

就像这样

代码语言:javascript
运行
复制
bool gasolineStationRule(const bankAccountEntry& bae)
{
    return (bae.name.find("gasolineStation1")!= std::string::npos) ||
           (bae.name.find("gasolineStation2")!= std::string::npos);
}

可以通过搜索"gasolineStation“一次来改进,然后,如果找到"gasolineStation”,则测试它后面的字符是否为“1”或“2”。

如何将rules放入向量中将非常有趣。它可能需要大量的专门函数,一大群Lambdas,或者一对树中的一只山鸡。问题中没有足够的详细说明来确定。

它可能看起来像这样

代码语言:javascript
运行
复制
mappings.push_back(mapping{&gasolineStationRule, "gasoline"})

或者通过向mapping添加构造函数

代码语言:javascript
运行
复制
mapping(std::function<bool(const bankAccountEntry&)> newrule,
        std::string newcategory): rule(newrule), category(newcategory)
{

}

你可能会得到一个小的性能提升。

代码语言:javascript
运行
复制
mappings.emplace_back(&gasolineStationRule, "gasoline")

不管怎样..。

代码语言:javascript
运行
复制
bool bankAccountEntry::categorize()
{
    for (const mapping & kvp: mappings)
    {
        if (kvp.rule(*this))
        {
            setCategory(kvp.category);
            return true;
        }
    }
    return false;
}

同样,您对规则以及它们的可预测性了解得越多,您就可以优化得越多。

作为bankAccountEntry::categorize核心的可能替代品的Also look at std::find_if

Documentation on std::function.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41942994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档