Ale*_*lex 22 c++ dictionary if-statement c++11
我写了一个应该将字符串转换为数字的函数.我看到两种可能的变体来写它:
int convert(const std::string input) {
if (input == "one") {
return 1;
} else if (input == "two") {
return 2;
}
// etc.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
要么
int convert(const std::string input) {
static const map<string, int> table = {
{"one", 1},
{"two", 2}
// etc.
}
const auto result = table.find(input);
if (result == table.end())
{
return 0;
}
return result->second;
}
Run Code Online (Sandbox Code Playgroud)
哪种方式更有效/可接受/可读?
phi*_*ipp 21
答案很大程度上取决于你将支持多少不同的字符串.
一些字符串:与if-else一起使用.稍后理解代码所需的努力很少.
很多字符串:创建一个地图.与阅读巨大的if-else结构的努力相比,理解代码的努力很小.可能,您必须经常扩展此列表.添加数据需要更少的输入.
我不确定C++的地图是如何使用字符串作为键的.在最坏的情况下,两者都具有相同的性能.如果列表变得非常庞大,您可能会想到创建字符串的哈希值并将其用作键.这可能会大大提高性能.你必须确保不会发生碰撞.(良好的散列算法和64位散列大小应该足够了.)可能现代地图实现已经这样做了.
对于一小组文本,我使用一个简单的查找表:
struct LookupTable {
const char* text;
int value;
};
const LookupTable table[] = {
{ "one", 1 },
{ "two", 2 }
};
int convert(const char* text) {
if (!text) return 0;
for (int i=0; i<sizeof(table)/sizeof(LookupTable); i++) {
if (strcasecmp(text, table[i].text) == 0 ) {
return table[i].value;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于大量文本,我会考虑使用std::unordered_map<std::string,int>,也许是自定义散列函数(bkdr散列或elf散列对单词很好).
编辑:正如大卫在评论中指出的那样,如果你不想要丑陋sizeof,请使用现代的for循环:
int convert(const char* text) {
if (!text) return 0;
for (auto& entry: table) {
if (strcasecmp(text, entry.text) == 0 ) {
return entry.value;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
一个if-else(或者switch,如果可用的话)适用于小案例,并且您还可以控制测试的顺序,以防最常见的测试可以快速切断搜索,您可以先测试它们.
在许多情况下,a switch远比if-elses 列表好.两者都更容易阅读,也可能更快.虽然switch不是最好的选择string.
然而,您可以打开enum而不是使用字符串; 这当然是更好的方法,除了a map.
对于大量可能性或者在运行时需要更新这些可能性时,A map或者std::unordered_map更好.
| 归档时间: |
|
| 查看次数: |
2266 次 |
| 最近记录: |