将长字符串列表映射到枚举的有效方法

时间:2017-07-10 19:40:31

标签: c++ search mapping

(我不确定如何正确地调用我的问题。如果有更好的说明方式,请编辑标题)

在我正在使用的API中,我有一个具有2000多个enumarator值的特定枚举器类型。我的目标是有一个函数,它将接受一个字符串并返回相应的枚举器。 (枚举器值和strings2具有几乎相同的名称。)

我的想法是嵌套if语句:

queriedEntityNameStringstd::stringqueriedEntityType是枚举类型)

//P
if (queriedEntityNameString[0] == 'p'){

    //PO
    if (queriedEntityNameString[1] == 'o'){

        if (queriedEntityNameString == "point")
            queriedEntityType = et_point;

        else if (queriedEntityNameString == "pocket")
            queriedEntityType = et_pocket;

        else if (queriedEntityNameString == "point_on_curve")
            queriedEntityType = et_point_on_curve;


    }
    //PR
    else if (queriedEntityNameString[1] == 'r'){

        if (queriedEntityNameString == "product")
            queriedEntityType = et_product;

        else if (queriedEntityNameString == "product_definition")
            queriedEntityType = et_product_definition;          

        else if (queriedEntityNameString == "product_definition_formation")
            queriedEntityType = et_product_definition_formation;

    }

}
//Q
else if (queriedEntityNameString[0] == 'q'){
    //QU
    if (queriedEntityNameString[1] == 'u'){

        if (queriedEntityNameString == "qualified_representation_item")
            queriedEntityType = et_qualified_representation_item;

        else if (queriedEntityNameString == "quantified_assembly_component_usage")
            queriedEntityType = et_quantified_assembly_component_usage;

    }
}

显然,手动设置2000个案例是“不可能的”。我可以编写一个可以为我做这个的小脚本,但这个脚本可以在某个地方使用吗?

我的第二个想法是把所有东西放在一个std :: map中,但我不确定它会有多高效。

我想就解决这个问题的最佳方法提出任何建议。

2 个答案:

答案 0 :(得分:1)

你的if-then-else条件链构成了一个穷人的#34;" trie数据结构。它很有效率,但在你的情况下可能有点过头了。

更好的方法是使用std::unordered_map,一个基于散列的容器,它检索与O(k)中的键相关联的值,其中k是键的大小(在您的情况下,字符串的最大长度)。

请注意,时间不取决于地图中的项目数量。这与std::map不同,后者需要O(log 2 n * k)时间,其中n是地图中的项目数。

答案 1 :(得分:0)

你真的需要它多快?

最简单的方法是使用数组,假设您的枚举按0到n-1排序:

enum class ProductProperty : unsigned { ... };

struct ProductProperties
{
    static constexpr char const * NAMES [] = { ... };
    static ProductProperty parse ( char const * const str )
    {
        auto const comparer = [str] ( char const * str_rep ) { return not strcmp ( str, str_rep ); };
        auto const position = std::find_if ( std::begin ( NAMES ), std::end ( NAMES ). comparer );
        return (ProductProperty) ( position - std::begin ( NAMES ) );
    }
}

如果你想要花哨,你可以构建一个自定义散列函数h,你在有效枚举的域上验证了它是唯一的,然后按照h对数组进行排序。然后解析一个字符串将等同于使用h进行散列,进行二进制搜索,然后再使用目标条目再加strcmp,如果有的话。