给定一个string数组p及其大小n,同时给定长字符串string s,请返回一个bool数组,元素为true或false对应p中的对应字符串是否为s的子串。要求p中的串长度小于等于8,且p中的串的个数小于等于500,同时要求s的长度小于等于1000。
测试样例:
["a","b","c","d"],4,"abc"
返回:[true,true,true,false]
class Substr {
public:
vector<bool> chkSubStr(vector<string> p, int n, string s) {
vector<bool> result;
for(int i = 0;i < n;++i){
if(s.find(p[i]) != -1){
result.push_back(true);
}//if
else{
result.push_back(false);
}//else
}//for
return result;
}
};
class Substr {
public:
struct TrieNode{
char c;
struct TrieNode* ptr[26];
TrieNode(char c):c(c){
memset(ptr,0,sizeof(ptr));
}
};
void insert(TrieNode *&root,const string &str,int i){
if(i >= str.size()){
return;
}
int index = str[i] - 'a';
if(root->ptr[index] == NULL){
root->ptr[index] = new TrieNode(str[i]);
cout<<str[i];
if(i == str.size() - 1){
return;
}
}
insert(root->ptr[index],str,i+1);
}
bool findSub(TrieNode *root,const string &str){
for(int i = 0; i < str.size(); i++){
TrieNode *node = root->ptr[str[i]-'a'];
if(node == NULL || node->c != str[i])
return false;
root = root->ptr[str[i]-'a'];
}
return true;
}
void build(TrieNode *&root,const string& str){
for(int i = 0; i < str.size(); i++){
insert(root,str,i);
cout<<endl;
}
}
vector<bool> chkSubStr(vector<string> p, int n, string s) {
vector<bool> vec;
if(p.size() < 1) return vec;
TrieNode* root = new TrieNode(0);
build(root,s);
for(int i = 0; i < p.size(); i++){
if(findSub(root,p[i])){
vec.push_back(true);
}else{
vec.push_back(false);
}
}
return vec;
}
};
import java.util.*;
public class Substr {
void insert(Node root,String str,int i){
if(i>=str.length())
return;
int index=str.charAt(i)-'a';
if(root.children[index]==null){
root.children[index]=new Node(str.charAt(i));
if(i==str.length()-1)
return;
}
insert(root.children[index], str, i+1);
}
boolean findSub(Node root,String str){
for(int i=0;i<str.length();++i){
Node node=root.children[str.charAt(i)-'a'];
if(node==null||node.c!=str.charAt(i))
return false;
root=root.children[str.charAt(i)-'a'];
}
return true;
}
void build(Node root,String str){
for(int i=0;i<str.length();++i){
insert(root, str, i);
}
}
public boolean[] chkSubStr(String[] p, int n, String s) {
// write code here
boolean[] re=new boolean[n];
if(p.length<1)
return re;
Node root=new Node('0');
build(root, s);
for(int i=0;i<p.length;++i){
if(findSub(root, p[i]))
re[i]=true;
else {
re[i]=false;
}
}
return re;
}
}
class Node {
private static final int D_size=26;
protected char c;
protected Node[] children=new Node[D_size];
Node(char c){
this.c=c;
}
}
//记得换一下类名
import java.util.*;
public class Main1 {
public boolean[] chkSubStr(String[] p, int n, String s) {
boolean[] arr=new boolean[n];
/**这里这么判断行倒是行,但是是O(n^2)复杂度呀
for(int x=0;x<arr.length;x++){
for(int i=0;i<p.length;){
if(s.contains(p[i])){
arr[x]=true;
}else {
arr[x]=false;
}
}
}*/
//因为s.contains本来返回的就是Boolean类型的值,所以直接赋值
//这里的因为这里的p.length==n,所以就不用放在新的for循环里
for (int i = 0; i < n; i++) {
arr[i] = s.contains(p[i]);
}
return arr;
}
}
// 大概是最容易想到的方法了
import java.util.*;
public class Substr {
public boolean[] chkSubStr(String[] p, int n, String s) {
// write code here
boolean[] res = new boolean[n];
for(int i=0;i<p.length;i++)
{
res[i] = isSubStr(p[i],s);
}
return res;
}
public boolean isSubStr(String sub,String s)
{
if(s.indexOf(sub) != -1)
return true;
else
return false;
}
}
记录每个字符出现的位置,子串从该位置开始比较
#include<unordered_map>
#include<unordered_set>
class Substr{
public:
vector<bool> chkSubStr(vector<string> p, int n, string s)
{
vector<bool> res(n, false);
unordered_map<char, unordered_set<int>> place;
for (int i = 0; i < s.size(); ++i)
{
place[s[i]].emplace(i);
}
for (int i = 0; i < n; ++i)
{
string str = p[i];
if (place.find(str[0]) != place.end())
{
for (auto& pos : place[str[0]])
{
if (pos + str.size() - 1 < s.size() &&
s.substr(pos, str.size()) == str)
{
res[i] = true;
break;
}
}
}
}
return res;
}
};
class Substr:
def chkSubStr(self, p, n, s):
root = Node()
for i in range(len(s)):
root.insert(s[i:])
return [root.search(x) for x in p]
class Node: #后缀树
def __init__(self):
self.child = {}
def insert(self, s):
if len(s) > 0:
c = s[0]
if c in self.child:
n = self.child[c]
else:
n = Node()
self.child[c] = n
n.insert(s[1:])
def search(self, s):
if len(s) == 0:
return True
c = s[0]
if c in self.child:
return self.child[c].search(s[1:])
return False
java 语言实现:
public boolean[] chkSubStr(String[] p, int n, String s) {
// write code here
boolean check[]=new boolean[n];
if(p==null||s==null)
return check;
for(int i=0;i<p.length;i++){
if(s.contains(p[i])){
check[i]=true;
}else{
check[i]=false;
}
}
return check;
}
import java.util.*;
class Node {
Character ch;
Map<Character, Node> map;
public Node(Character ch) {
this.ch = ch;
map = new HashMap<Character, Node>();
}
//方便对map进行操作,因此进行了重写。。不然每次都得多加.map。
public boolean containsKey(Character ch){
return map.containsKey(ch);
}
public Node get(Character ch){
return map.get(ch);
}
public Node put(Character ch, Node node){
return map.put(ch, node);
}
}
public class Substr {
public boolean[] chkSubStr(String[] p, int n, String s) {
// write code here
Node root = new Node('0');
List<Node> list = new ArrayList<>();
int len = s.length();
//建树
for(int i = 0; i < len; i++) {
int oldSize= list.size();
char key = s.charAt(i);
//列表保存每一步达到的节点,下一次会从这些位置开始,再加上从root开始查找
List<Node> newList = new ArrayList<>();
for(int j = 0; j < oldSize; j++) {
Node node = list.get(j);
if(node.containsKey(key)) {
newList.add(node.get(key));
} else {
Node child = new Node(key);
node.put(key, child);
newList.add(node.get(key));
}
}
//从root开始查找 if(root.containsKey(key)){
newList.add(root.get(key));
} else {
Node child = new Node(key);
root.put(key, child);
newList.add(root.get(key));
}
list = newList;
}
boolean[] resu = new boolean[n];
for(int i = 0; i < n; i++) {
String str = p[i];
Node node = root;
boolean flag = true;
for(int j = 0; j < str.length(); j++) {
char key = str.charAt(j);
if(node.containsKey(key)) {
node = node.get(key);
} else {
flag = false;
break;
}
}
resu[i] = flag;
}
return resu;
}
}
public class Substr {
public boolean[] chkSubStr(String[] p, int n, String s) {
boolean[] f=new boolean[n];
for(int i=0;i<n;i++){
f[i]=s.indexOf(p[i])>=0?true:false;
}
return f;
}
}
public static boolean[] chkSubStr(String[] p, int n, String s) {
//记录26个字母出现的位置
ArrayList<Integer>[] lists= new ArrayList[26];
for (int i = 0; i < lists.length; i++) {
lists[i]=new ArrayList<>();
}
int i=0;
int pos=0,z=0,q=0,length=0;
boolean flag=false;
while(i<s.length()) {
q=s.charAt(i)-97;
lists[q].add(i);
i++;
}
boolean[] bs=new boolean[p.length];
for (int j = 0; j < p.length; j++) {
pos=p[j].charAt(0)-97;
z=0;
flag=false;
length=p[j].length();
//根据2维数组记录的位置通过substring进行比较
while(flag==false&&z<lists[pos].size()) {
if (s.substring(lists[pos].get(z),Math.min(lists[pos].get(z)+length, s.length())).equals(p[j])) {
flag=true;
}
z++;
}
bs[j]=flag;
}
return bs;
}