我們的系統需要接受來自終端的用戶輸入並且匹配幾個已知的關鍵字字符串(可能是10)。在C中匹配(幾個)字符串的最有效方法?
我們沒有空間/化合物來做正則表達式等等,代碼需要很小&快。
現在,討厭的方式做到這一點是:
// str is null-terminated, assume we know it's safe/sane here
if(!strncmp(str,"hello",5)
{
do_hello();
}
else if(!strncmp(str,"world",5)
{
do_world();
}
else
{
meh(); // Wasn't a match
}
所以,有點谷歌上搜索&讀的,我深信,一個更好的辦法是預先計算各種比賽的哈希後作爲一個int,然後只用一個case語句:
// Assume hash() stops at NULL
switch(hash(str))
{
case HASH_OF_HELLO:
do_hello();
break;
case HASH_OF_WORLD:
do_world();
break;
default:
meh();
break;
}
我們可以計算出* HASH_OF_match *在編譯時。這看起來似乎是從相對較小的集合中選擇字符串的更快/更優雅的方式。
所以 - 這看起來是否合理? /這樣做有沒有明顯的問題? /任何人都有一個更優雅的方式來做到這一點?
作爲一個腳註,這是我今天下午看到的最好看的哈希算法;),記入丹伯恩斯坦,它看起來就在眼前的工作。
unsigned int
get_hash(const char* s)
{
unsigned int hash = 0;
int c;
while((c = *s++))
{
// hash = hash * 33^c
hash = ((hash << 5) + hash)^c;
}
return hash;
}
這是一個有趣的散列函數。您能否正確引用它(例如提供一個鏈接到伯恩斯坦的描述),所以我可以更多地瞭解它? –
如果這是從用戶輸入的輸入測試字符串,那麼真的沒有理由擔心'strcmp()'和if/else決策樹超過10個項目的速度。散列解決方案將起作用(只要對付垃圾投入的散列衝突不是一個擔心,它可能不是),但它會讓我覺得過度殺傷,最終可能會成爲維護麻煩。標準的二進制搜索查找關鍵字排序表到關鍵字ID將很容易足夠快速(查找匹配到10個項目的輸入匹配的線性表查找將非常快)。 –
@MichaelBurr - yup,const char指針的const數組的strcmp()線性搜索是我通常用於終端樣式的UI,通常使用枚舉索引,然後我可以切換到調用實現命令動詞。 –