3

这听起来像是一个基本问题,当然可以解决,但我正在寻找一个快速而优雅的解决方案。

我想为我的程序创建一组保留字: {"apple", "orange", "peach"}

它是恒定的,我希望能够在运行时检查字符串s是否是保留字(fs是集合的一部分)。

我考虑过使用std::set,但我不想手动将我的每个保留字添加到集合中。此外,我不需要 set 的全部功能,例如我不需要添加新元素或删除元素。

什么是优雅的做法?

4

3 回答 3

6

您可以将单词存储在数组中,然后使用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 中的 newbeginend函数,但您也可以在 C++03 中使用指向数组的第一个元素和最后一个元素的指针来执行此操作。

在 C++11 中,您还可以使用初始化列表来初始化std::set,尽管并非所有编译器都支持此功能。

还要注意,如果单词集的内容永远不会改变,最好简单地使用 sorted std::vector<std::string>withstd::lower_boundstd::binary_search查找元素。您可能会发现这会表现得更好。

于 2012-06-09T21:46:46.267 回答
6

在现代 c++ (c++11) 中:

const std::set<std::string> v = { "xyzzy", "plugh", "abracadabra" };
于 2012-06-09T21:49:53.590 回答
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[] = { ... }. 这将完全避免任何运行时初始化的需要。尽管您最好在源代码中正确排序,否则当您尝试使用排序序列搜索算法之一搜索单词时,您会遇到意外的行为。

此外,我不需要 set 的全部力量

我不认为这是避免它的好理由。避免某事的更好理由是它是否允许您想要禁止的事情。例如,如果你真的想防止添加和删除东西,那么使用非常量集就不是最好的选择。但是由于您可以使用 const set 来代替,因此无需避免 set。

于 2012-06-09T21:50:50.137 回答