程序将接收一个代表字符的向量。 然后将接收到的向量与代表字符的所有已知向量进行比较。
我不确定应该如何使用已知向量。
我想到的一些选择:
1)使用全局变量:
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';
}
答案 0 :(得分:4)
这听起来像是perfect hash generator的应用程序(链接到GNU gperf)。
引用文档
gperf是用C ++编写的完美的哈希函数生成器。它 将n元素用户指定的关键字集W转换为完美 哈希函数F。F将W中的关键字唯一地映射到范围0..k, 其中k> = n-1。如果k = n-1,则F是最小完美散列函数。 gperf生成一个0..k元素静态查找表和一对C 功能。这些函数确定给定的字符串 s出现在W中,最多使用一个对查询表的探测。
如果这不是合适的解决方案,那么我建议使用函数静态函数。您要避免使用函数局部变量,因为这会严重影响性能,并且全局变量会污染您的命名空间。
类似
char getLetter(const vector<int> &input){
static vector<int> charA{1,2,3,4,5};
static vector<int> charB{5,3,7,1};
答案 1 :(得分:0)
给你摘要,我去:
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
转换为适合作为映射键的键的函子,并以相同的方式对其进行初始化。
如上,但使用std :: unordered_map。
按照上面@PaulFloyd的建议使用gperf
答案 2 :(得分:0)
我首先建议您对二进制集合中的数字进行散列或表示,以便您不必每次都比较向量,因为这样做会非常昂贵。就是说,您的问题是关于如何制作字典的,所以无论您是否按照我的建议改进键,我都希望使用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
构造为常量。如果必须确保已完成所有字母的查找,必须先查找映射,那么显然不能构造常数。无论哪种方式,此map
应该是负责翻译字符串的类的私有成员。添加和映射应该是该类的公共功能。