2009-08-21 100 views
1

if陳述看起來太尷尬,因爲我需要增加constatnts數量的可能性。 對不起,由於這個「常量」,而不是我的意思,導致你陷入妄想。將字符串變量與一組字符串常量進行比較的最佳方法是什麼?

+3

您確定要比較一個**常數**和一組**常量**嗎?這個測試的結果是靜態的,對吧? – 2009-08-21 11:12:15

+0

他可能意味着一個常量字符串的非常量指針:const char * blah =「foo」;如果(isRiemannHypothesisTrue())blah =「bar」;'。然後檢查blah是否在集合中。 – 2009-08-21 11:30:42

+0

to onebyone - 我想我已經發布qustion之前思考=)我需要解析一個字符串,所以當該函數看到一個關鍵字時,應該用其他字符串值替換它。 – mknight 2009-08-21 11:46:14

回答

2

將字符串在靜態向量或集合中進行比較,然後使用std :: find算法。

+4

不要在集合或地圖上使用std :: find。成員函數查找對於這些類型效率更高 – Glen 2009-08-21 11:12:52

+0

是的,您是對的。 – Naveen 2009-08-21 11:13:35

9

所有的常量添加到一個std ::設置,那麼您可以檢查組包含

std::set<std::string> myLookup; 
//populate the set with your strings here 

set<std::string>::size_type i; 

i = myLookup.count(searchTerm); 
if(i) 
    std::cout << "Found"; 
else 
    std::cout << "Not found"; 
+1

Scott Meyers建議你在這裏使用'count'而不是'find'。這也是更少的代碼。 – 2009-08-21 11:24:37

+0

他會是對的。我只是忘記了所有關於count的內容,在很長一段時間裏我並沒有使用std :: set。我會更新我的回答 – Glen 2009-08-21 11:29:32

+0

請記住,該設置應該是靜態的,並且只有當它是空的時候才被填充,或者只是確保它對您可用,但只需要填充一次,如果您希望它有效地工作;) – RnR 2009-08-21 11:59:43

0
const char * values[]= { "foo", "bar", ..., 0 }; 

bool IsValue(const std::string & s) { 
    int i = 0; 
    while(values[i]) { 
     if (s == values[i]) { 
     return true; 
     } 
     i++; 
    } 
    return false; 
} 

你的字符串或者使用一個std ::設置。

3

取決於您是否關心性能。

如果不是,那麼最簡單的代碼可能會將各種字符串放入一個數組(或者說,如果您的意思是在運行時增加常量的話,就是向量)。這也將是少數串的相當快:

static const char *const strings[] = { "fee", "fie", "fo", "fum" }; 
static const int num_strings = sizeof(strings)/sizeof(char*); 

然後:

int main() { 
    const char *search = "foe"; 
    bool match = false; 
    for (int i = 0; i < num_strings; ++i) { 
     if (std::strcmp(search, strings[i]) == 0) match = true; 
    } 
} 

或者:

struct stringequal { 
    const char *const lhs; 
    stringequal(const char *l) : lhs(l) {} 
    bool operator()(const char *rhs) { 
     return std::strcmp(lhs, rhs) == 0; 
    } 
}; 

int main() { 
    const char *search = "foe"; 
    std::find_if(strings, strings+num_strings, stringequal(search)); 
} 

[警告:我沒有測試上面的代碼,我已經有幾次錯誤的簽名了...]

如果你關心性能,並且有一個reas可以使用的字符串數量,那麼一個快速選項就像Trie。但是,這是很多努力,因爲標準C++庫中沒有一個。你可以得到多少好處或者使用一個有序數組/矢量,搜索與std::binary_search

// These strings MUST be in ASCII-alphabetical order. Don't add "foo" to the end! 
static const char *const strings[] = { "fee", "fie", "fo", "fum" }; 
static const int num_strings = sizeof(strings)/sizeof(char*); 

bool stringcompare(const char *lhs, const char *rhs) { 
    return std::strcmp(lhs, rhs) < 0; 
} 

std::binary_search(strings, strings+num_strings, "foe", stringcompare); 

...或使用std::set。但是,除非在運行時更改字符串集合,否則使用二元搜索的排序數組無法使用集合,並且集合(或向量)必須用代碼填充,而數組可以靜態初始化。我認爲C++ 0x將改善事情,集合的初始化列表。

+0

+1提及排序的向量'用'binary_search'。 – avakar 2009-08-21 11:22:22

1

技術上最好的解決方案是:爲您的字符串常量集合建立一個「完美散列函數」,以便稍後在散列期間不會發生衝突。

+0

我喜歡這個想法,但問題是 - 不僅是不斷碰撞,而且還有可能的輸入字符串。 – 2009-08-21 12:07:37

相關問題