[英]Which data structure and algorithm is appropriate for this?
我有一千串。 给定一个需要在所有字符串中搜索的模式,然后返回包含该模式的所有字符串。
目前,我正在使用vector来存储原始字符串。 搜索模式,如果匹配,则将其添加到新向量中,最后返回向量。
int main() {
vector <string> v;
v.push_back ("maggi");
v.push_back ("Active Baby Pants Large 9-14 Kg ");
v.push_back ("Premium Kachi Ghani Pure Mustard Oil ");
v.push_back ("maggi soup");
v.push_back ("maggi sauce");
v.push_back ("Superlite Advanced Jar");
v.push_back ("Superlite Advanced");
v.push_back ("Goldlite Advanced");
v.push_back ("Active Losorb Oil Jar");
vector <string> result;
string str = "Advanced";
for (unsigned i=0; i<v.size(); ++i)
{
size_t found = v[i].find(str);
if (found!=string::npos)
result.push_back(v[i]);
}
for (unsigned j=0; j<result.size(); ++j)
{
cout << result[j] << endl;
}
// your code goes here
return 0;
}
是否有任何最佳方法可以以更低的复杂度和更高的性能实现相同目标?
我认为适合您的应用程序的容器。
但是,如果您实现自己的KMP algorithm
,则可以代替std::string::find
,而是可以保证时间复杂度在字符串+搜索字符串的长度方面是线性的。
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
因此, std::string::find
的复杂性是不确定的。
http://www.cplusplus.com/reference/string/string/find/
编辑:如此链接所指出,如果您的字符串的长度不大(大于1000),则可能使用std::string::find
就足够了,因为这里不需要制表等。
C ++ string ::发现复杂性
如果结果与输入字符串向量在同一代码块中使用(在您的示例中就是这样),或者即使您保证每个人都仅在输入存在时才使用结果,则实际上不需要复制字符串。 这可能是一个昂贵的操作,从而大大降低了整个算法的速度。
相反,您可以将指针向量作为结果:
vector <string*> result;
如果字符串列表在许多搜索中都是“固定的”,那么您可以使用倒排索引进行一些简单的预处理,从而大大加快处理速度。
构建字符串中存在的所有字符的映射,换句话说,为每个可能的字符存储一个包含该字符的所有字符串的列表:
std::map< char, std::vector<int> > index;
std::vector<std::string> strings;
void add_string(const std::string& s) {
int new_pos = strings.size();
strings.push_back(s);
for (int i=0,n=s.size(); i<n; i++) {
index[s[i]].push_back(new_pos);
}
}
然后,当被要求搜索子字符串时,您首先要检查反向索引中的所有字符,然后仅在条目数最少的索引的列表上进行迭代:
std::vector<std::string *> matching(const std::string& text) {
std::vector<int> *best_ix = NULL;
for (int i=0,n=text.size(); i<n; i++) {
std::vector<int> *ix = &index[text[i]];
if (best_ix == NULL || best_ix->size() > ix->size()) {
best_ix = ix;
}
}
std::vector<std::string *> result;
if (best_ix) {
for (int i=0,n=best_ix->size(); i<n; i++) {
std::string& cand = strings[(*best_ix)[i]];
if (cand.find(text) != std::string::npos) {
result.push_back(&cand);
}
}
} else {
// Empty text as input, just return the whole list
for (int i=0,n=strings.size(); i<n; i++) {
result.push_back(&strings[i]);
}
}
return result;
}
可能有许多改进:
std::set_intersection
)。 根据问题的参数(搜索多少个字符串,搜索多长时间,搜索多长时间……),它们是否都有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.