题目描述
现在有一个字符串列表,和一个关键词列表,请设计一个高效算法,检测出含关键字列表中关键字(一个或多个)的字符串。
给定字符串数组A及它的大小n以及关键词数组key及它的大小m,请返回一个排好序的含关键词的字符串序号的列表。保证所有字符串长度小于等于100,关键词个数小于等于100,字符串个数小于等于200。保证所有字符串全部由小写英文字符组成。若不存在含关键字的字符串,请返回一个只含-1的数组。
["nowcoder","hello","now"],3,["coder",now],2
返回:[0,2]
这道题其实就是一道加强版的子字符串的查询。但由于string类型的特别,其方法也有很多,这里给出两种解题思路:
1.利用string中的substr函数,
方法优缺点:调用系统函数,代码量小,但运行速度略慢
substr(start,length); 子字符串获取函数
带两个参数,第一个是子串的起始位置(从0开始),第二个是子串的长度。
solutions
class KeywordDetect {
public:
vector<int> containKeyword(vector<string> A, int n, vector<string> keys, int m) {
// write code here
int i,j;
int len=0;
vector<int> res;
int index=0;
int len_key;
int flag=0;
int old_i;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
for(len_key=0;len_key<=A[i].size()-keys[j].size();len_key++){
if (A[i].substr(len_key,keys[j].size())==keys[j]){
if(i!=old_i)
res.push_back(i);
old_i=i;
flag=1;
break;
}
}
if(i==old_i)
break;
}
}
if(flag==0)
res.push_back(-1);
return res;
}
};
有几点要注意的是:
1.flag是表示如果flag为0,也就是没有任何的字符串匹配。则返回-1数组。
2.old_i是用来指示不要出现重复的数组,比如第一个数组abcde,然后子字符串有ab和de,那么第一个ab后,将i=0存入res,然后第二个de就不用存了,因为已经有了。所以当old_i等于i,就表示有多个子字符串都在i这个字符串中,就要舍弃。
3.len_key表示substr的第一个参数,也就是子字符串的起始位置。
2.利用for循环遍历string每一个元素
方法优缺点:最底层的代码,运行速度快,但代码量大
class KeywordDetect {
public:
vector<int> containKeyword(vector<string> A, int n, vector<string> keys, int m) {
// write code here
int i,j;
int len=0;
vector<int> res;
int index=0;
int len_key;
int old_i;
int flag=0;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
len_key=keys[j].size();
len=0;
for(auto c : A[i]){
if(c==keys[j][len]){
len++;
}
else{
len=0;
}
if(len==len_key){
if(i!=old_i)
res.push_back(i);
old_i=i;
len=0;
flag=1;
break;
}
}
if(old_i==i)
break;
}
}
if(flag==0)
res.push_back(-1);
return res;
}
};