尝试制作一个简单的程序来编目书籍。像这样的东西,例如:
struct book{
string author;
string title;
int catalogNumber;
}
最终,我希望能够根据范围进行标题搜索。因此,用户可以指定显示书籍的结果,其中标题以“aa”开头,但是“be”。理想情况下,搜索平均情况是对数的。
STL中有什么东西可以帮助我吗?否则,最好的方法是什么?
谢谢!
答案 0 :(得分:4)
您可以将它们存储在std::set
中,并使用std::lower_bound
和std::upper_bound
来查找范围(是的,这应该是对数的)。为此,您需要定义operator<
以仅对您关注的字段进行操作(在这种情况下为title
)。
如果您(实际上)始终将标题视为关键字,您可能更愿意使用std::map<std::string, info>
,info
定义为:
struct info {
string author;
int catalogNumber;
info(string a, int c) : author(a), catalogNumber(c) {}
};
这使得一些操作更容易,例如:
books["Moby Dick"] = info("Herman Melville", 1234);
如果您想支持按标题或作者搜索(例如),请考虑使用Boost bimap或multi_index之类的内容。
对于它的价值,我还要认真地想到使用string
而不是int
作为目录号。标准编号系统(例如,杜威十进制,国会图书馆,ISBN)几乎都不会很好地存储在一个整数中。
答案 1 :(得分:1)
您可以将元素放在std::set
中。问题在于,您可能希望您的用户能够按标题和作者进行搜索。解决方案只是维护两组,但如果您的数据发生变化,维护起来可能会很棘手,而且您需要两倍的空间。
您总是可以编写类似Trie的内容,但很可能您的数据会发生变化,并且维持对数搜索时间变得更加困难。您可以实现任何类型的Self-balancing binary search tree,但这基本上是set
- Red-black tree。写一个不是最简单的任务,但是......
更新:您可以散列所有内容并实现某种形式的Rabin-Karp string search algorithm,但是您应该知道如果您这样做可能会发生冲突。您可以通过双重散列和/或使用良好的散列函数来降低其概率。
答案 2 :(得分:1)
您可以使用trie [在此扩展@smarinov建议]:
在trie中查找具有公共前缀的相关单词集非常容易,只需按照trie中的指针,直到到达表示所需公共前缀的节点。此节点是包含所需公共前缀的trie。
在您的示例中,您将需要:
range("aa","be") = prefix("a") + (prefix("b[a-e]")
此OP的预期复杂度为O(|S|)
,其中|S|
是公共前缀的长度。请注意,任何算法都不会比[O(logn)
算法实际上O(|S| * logn)
更好,因为比较操作取决于字符串的长度。