2012-06-09 80 views
3

這可能聽起來像一個基本問題,它當然可以解決,但我正在尋找一個快速和優雅的解決方案。創建一個常量集合的字符串C++

我想創建的我的程序保留字的集合: {"apple", "orange", "peach"}

這是不變的,我想在運行時可以檢查是否字符串s是保留字(F s是一部分該集)。

我想過使用std::set,但我不想將每個保留字都手動添加到該設置。另外,我不需要全部的設定功能,例如我不需要添加新元素或刪除元素。

這是幹什麼的?

+0

如果你不想用'std :: set'來表示一個集合,可以使用一個數組和'std :: find'。 –

回答

5

您可以將單詞存儲在數組中,然後使用std::set範圍構造:

char const* raw_words[] = { "apple", "orange", "peach" }; 

std::set<std::string> const words(std::begin(raw_words), std::end(raw_words)); 

這使得利用在C++ 11的新beginend功能,但你也可以做到這一點的C++ 03使用指向數組的第一個和最後一個元素的指針。

在C++ 11中,您還可以使用初始化程序列表初始化std::set,但並非所有的編譯器都支持此功能。

還請注意,如果單詞集的內容永不改變,則最好簡單地使用排序的std::vector<std::string>std::lower_boundstd::binary_search來查找元素。你可能會發現這樣會更好。

+0

這就是我需要的。試圖用字符串數組而不是'char *'來做到這一點。謝謝。 – Michael

+0

'std :: string raw_words []'也可以正常工作。我選擇了'char const *'來避免'std :: string'不必要的開銷。由於'raw_words'的唯一用法是初始化'words',因此不需要'std :: string'的特性。 –

6
在現代C++

(C++ 11):

const std::set<std::string> v = { "xyzzy", "plugh", "abracadabra" }; 
+1

'std :: set'和'std :: string'都不是'constexpr'友好的:https://godbolt.org/g/CmvaZa-你應該刪除你的答案**以避免誤傳。 –

+0

@VittorioRomeo我用'const'替換了'constexpr' – log0

+0

公平的 - 恢復我的downvote。 –

2

我不希望我的保留字每一個手動添加到組。

如果你的意思是你不想要的代碼看起來像:

reserved_word.insert("apple"); 
reserved_word.insert("orange"); 
reserved_word.insert("peach"); 
在具有運行前的一切,你可以改爲做一些初始化代碼

(在C++ 11 ):

const std::set<std::string> reserved_word = {"apple", "orange", "peach"}; 

雖然這仍然在運行時執行初始化。

您也可以簡單地使用預先排序的char const *reserved_word[] = { ... }。這將避免任何運行時初始化的需要。儘管您最好在源代碼中正確排序,但當您嘗試使用排序後的搜索算法之一搜索某個詞時,您會得到意想不到的行爲。

除此之外,我不需要設定

的全部力量,我不相信這是一個很好的理由,以避免它。避免某些事情的一個更好的理由是如果它允許你想要禁止的事情。例如,如果你真的想要防止添加和刪除東西,那麼使用非常量集合將不是最好的選擇。但是,既然你可以使用const set,那麼就沒有必要避免設置。

相關問題