C++ 哪种数据结构和算法适用于此?
我有1000根绳子。给定需要在所有字符串中搜索的模式,并返回包含该模式的所有字符串 目前,我正在使用vector for来存储原始字符串。搜索一个模式,如果匹配,将其添加到新向量中,最后返回向量C++ 哪种数据结构和算法适用于此?,c++,string,algorithm,stl,C++,String,Algorithm,Stl,我有1000根绳子。给定需要在所有字符串中搜索的模式,并返回包含该模式的所有字符串 目前,我正在使用vector for来存储原始字符串。搜索一个模式,如果匹配,将其添加到新向量中,最后返回向量 int main() { vector <string> v; v.push_back ("maggi"); v.push_back ("Active Baby Pants Large 9-14 Kg "); v.push_back ("Premium Kac
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;
}
intmain(){
向量v;
v、 推回(“maggi”);
v、 后推(“活动婴儿裤大码9-14公斤”);
v、 推回(“优质Kachi Ghani纯芥末油”);
v、 推回(“maggi汤”);
v、 向后推(“玛吉酱”);
v、 向后推(“Superlite高级震击器”);
v、 向后推(“Superlite Advanced”);
v、 向后推(“Goldlite Advanced”);
v、 向后推(“主动Losorb油罐”);
矢量结果;
string str=“高级”;
对于(unsigned i=0;i我认为适合您的应用程序的容器
但是,如果您实现自己的KMP算法
,则可以保证时间复杂度与字符串+搜索字符串的长度成线性关系,而不是std::string::find
。
因此,std::string::find
的复杂性未指定。
编辑:正如此链接所指出的,如果字符串的长度不大(超过1000),那么可能使用std::string::find
就足够了,因为这里不需要制表等功能。
如果结果与输入字符串向量在同一代码块中使用(在您的示例中就是这样),或者即使您保证每个人都只在输入存在时使用结果,您实际上也不需要复制字符串。这可能是一个昂贵的操作,会大大降低整个算法的速度
相反,您可以使用指针向量作为结果:
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::mapindex;
std::向量字符串;
void add_字符串(const std::string&s){
int new_pos=strings.size();
字符串。向后推_(s);
对于(int i=0,n=s.size();i ix->size()){
最佳_ix=ix;
}
}
std::向量结果;
如果(最佳九){
对于(int i=0,n=best_ix->size();i如果源文本很大且是静态的(例如,爬网的网页),则可以通过预先构建一个或一个数据结构来节省搜索时间。搜索模式可以遍历树以查找匹配项
如果源文本很小并且经常更改,那么您最初的方法是合适的。STL函数通常经过了很好的优化,并且经受了时间的考验。听起来像是grep
的工作……您可以只保存匹配字符串的索引,而不是字符串本身。因此结果
变成vector
只存储索引。你可以乱搞后缀树,你会得到更低的渐近复杂度——构建事物的线性时间和与查询字符串长度加上查询输出数量成比例的时间。不过,这涉及到一个相当高的常数因子;在你的尺度上,这不值得。只需使用strstr
。高质量的实现有一个在线性时间和恒定空间中运行的strstrstr
。strstr
对于std::string
来说不是一个好的选择,因为std::string可能有嵌入的空值,并且在任何情况下都有一个已知的长度。并且没有理由使用它,因为std::find
在没有b的情况下也做同样的事情使用过时的C库函数。@Sneftel:OP的输入中没有嵌入空值的字符串。如果你在寻找性能,因为嵌入空值而将复杂度提高到二次不是一个好主意,而OP据说是这样。@tmyklebu为什么不使用KMP算法?@AbhishekBansal:str
,它已经存在,并且可能会出现KMP的辅助数组会导致相当严重的性能下降——对于短字符串,因为您必须构建它,而对于长字符串,因为额外的缓存压力。顺便说一句,这是您可以自己尝试看看的事情之一。您是你能有一个参考向量吗?
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;
}