[英]Fast and maintainable way of implementing string to integer lookup table
我可以找到很多關於如何將 map 和 integer 轉換為字符串常量的問題,有明顯的解決方案
char const* strings[] = {"Foo", "Bar", ...};
現在,假設我想要相反:我有字符串“Bar”,並且想要 1。我的字符串最多 4 個字符,並且 ascii null 不是有效值。 map 值有 64 個整數。 我是否必須編寫一個帶有字符串比較的長 if-else 構造,還是有更好的東西。
澄清一下,我更喜歡不需要運行時初始化的解決方案,從 C++17 開始,這使得無法使用std::map
或std::unordered_map
。
我的字符串最多 4 個字符,ascii null 不是有效值。
在這種情況下,您可以將字符串轉換為 integer,並使用您最喜歡的編譯時整數到整數 map。
例如,使用switch
:
#include <cstddef>
#include <cstdint>
namespace detail {
constexpr std::uint64_t string_as_int(const char* string) noexcept {
std::uint64_t result = 0;
std::uint64_t i = 0;
for (; i < 4 && *string; ++string, ++i) {
result |= static_cast<std::uint64_t>(static_cast<unsigned char>(*string)) << (i * 8u);
}
return result;
}
constexpr std::uint64_t operator ""_h(const char* string, std::size_t) noexcept {
return string_as_int(string);
}
}
constexpr int lookup(const char* string) {
using detail::operator ""_h;
switch (detail::string_as_int(string)) {
case "Foo"_h: return 1;
case "Bar"_h: return 2;
default: return 0;
}
}
您應該使用std::map
除非您需要更好/自定義的東西。
std::map<std::string, int> stringToPos;
stringToPos["Foo"] = stringToPos.size(); // there's other ways to init the map, but you can fill it up this way too
stringToPos["Bar"] = stringToPos.size();
stringToPos["Bleh"] = stringToPos.size();
std::cout << stringToPos["Bleh"] << std::endl;
填充 map 的另一種選擇是:
for(auto s:{"foo","bar","bleh"})
{
stringToPos[s] = stringToPos.size();
}
如果您可以使用 c++17 我會使用unordered_map
和string_view
。 就像是
#include <iostream>
#include <string_view>
#include <unordered_map>
int main(){
std::array<char const*,2> strings = { "Foo", "Bar" };
std::unordered_map<std::string_view,int> map;
for( int i = 0 ; i != strings.size(); ++i )
map[strings[i]] = i;
std::cout << map["Foo"];
}
在此處查看工作版本:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.