代码之家  ›  专栏  ›  技术社区  ›  daniel

使用大量已知常量变量的正确方法

c++
  •  1
  • daniel  · 技术社区  · 7 年前

    程序接收表示字符的向量。 然后将接收到的向量与表示字符的所有已知向量进行比较。

    我不知道如何使用已知的向量。

    vector<int> charA{1,2,3,4,5};
    vector<int> charB{5,3,7,1};
    ...
    vector<int> charZ{3,2,5,6,8,9,0}
    
    char getLetter(const vector<int> &input){
        if(compareVec(input,charA) return 'A';
        if(compareVec(input,charB) return 'B';
        ....
        if(compareVec(input,charZ) return 'Z';
    
    }
    

    2) 声明函数中的所有变量:

     char getLetter(const vector<int> &input){
            vector<int> charA{1,2,3,4,5};
            vector<int> charB{5,3,7,1};
            ...
            vector<int> charZ{3,2,5,6,8,9,0}
    
            if(compareVec(input,charA) return 'A';
            if(compareVec(input,charB) return 'B';
            ....
            if(compareVec(input,charZ) return 'Z';
    
        }
    

    3) 传递变量

    char getLetter(const vector<int> &input, vector<int> charA,
          vector<int> charB... , vecotr<int> charZ){
            if(compareVec(input,charA) return 'A';
            if(compareVec(input,charB) return 'B';
            ....
            if(compareVec(input,charZ) return 'Z';
    
        }
    
    3 回复  |  直到 7 年前
        1
  •  4
  •   Paul Floyd    7 年前

    perfect hash generator (链接到GNU gperf)。

    引用文档

    将n元素用户指定的关键字集W转换为 散列函数F。F唯一地将W中的关键字映射到范围0..k上, 其中k>=n-1号。如果k=n-1,那么F是一个最小完美散列函数。 功能。这些函数确定给定的字符串

    如果这不是一个合适的解决方案,那么我建议使用函数静态。您希望避免使用函数局部变量,因为这将严重影响性能,而全局变量将污染您的命名空间。

    比如说

    char getLetter(const vector<int> &input){
        static vector<int> charA{1,2,3,4,5};
        static vector<int> charB{5,3,7,1};
    
        2
  •  0
  •   peterchen    7 年前

    char getLetter(const vector<int> &input)
    {
        struct 
        {
           char result;
           std::vector<char> data; 
        } const data[]=
        {
           { 'A', {1,2,3,4,5}, },
           { 'B', {5,3,7,1}, },
           ...
        };
    
        for(auto const & probe : data)
        {
            if (comparevec(input, probe.data))
               return probe.result;
        }
    
        // input does not match any of the given values
        throw "That's not the input I'm looking for!"; 
    }
    

    对于40个这样的对,如果不是在一个紧密的内部循环中调用,那么线性搜索就足够了。

    选择:

    • 使用 std::map<std::vector<char>, char> 将有效值映射到结果,然后 compareVec 变成一个适合作为映射的键的函子,并以同样的方式初始化它。

    • 按照上面@PaulFloyd的建议,使用gperf

        3
  •  0
  •   Jonathan Mee    7 年前

    我首先建议您散列或表示二进制集合中的数字,这样您就不会每次都比较向量,因为这将证明是非常昂贵的。也就是说,你的问题是如何制作一本字典,所以不管你是否按照我的建议改进了你的键,我更喜欢使用 map :

    map<vector<int>, char, function<bool(const vector<int>&, const vector<int>&)>> dictionary([](const auto& lhs, const auto& rhs){
        const auto its = mismatch(cbegin(lhs), cend(lhs), cbegin(rhs), cend(rhs));
    
        return its.second != cend(rhs) && (its.first == cend(lhs) || *its.first < *its.second);
    });
    

    如果可能的话 dictionary initializer_list 包含所有映射和比较器。如果在保证完成所有字母之前必须查找映射,那么显然不能构造常量。不管怎样 地图

    Live Example