牛牛有两个字符串A和B,其中A串是一个01串,B串中除了可能有0和1,还可能有'?',B中的'?'可以确定为0或者1。 寻找一个字符串T是否在字符串S中出现的过程,称为字符串匹配。牛牛现在考虑所有可能的字符串B,有多少种可以在字符串A中完成匹配。
例如:A = "00010001", B = "??"
字符串B可能的字符串是"00","01","10","11",只有"11"没有出现在字符串A中,所以输出3
输入包括两行,第一行一个字符串A,字符串A长度length(1 ≤ length ≤ 50),A中每个字符都是'0'或者'1'。 第二行一个字符串B,字符串B长度length(1 ≤ length ≤ 50),B中的字符包括'0','1'和'?'。
输出一个整数,表示能完成匹配的字符串种数。
00010001 ??
3
def solution(A,B):
if len(B)>len(A):
return 0
s=len(B)
count=0
res=[]
for i in range(len(A)-s+1):
t=0
for j in range(s):
if B[j]=='?' or B[j]==A[i:i+s][j]:
t+=1
if t==s:
res.append(A[i:i+s])
else:
break
return len(set(res))
A=raw_input().strip()
B=raw_input().strip()
print solution(A,B)
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); String A = sc.nextLine(); String B = sc.nextLine(); StringBuilder sb = new StringBuilder(); //将sb装换成模式匹配 for(int i=0; i<B.length(); i++) if(B.charAt(i) == '?') sb.append("[01]{1}"); else sb.append(B.charAt(i)); Set<String> res = new HashSet<>(); for(int i=0; i<=A.length()-B.length(); i++){ String sub = A.substring(i, i+B.length()); if(sub.matches(sb.toString())) res.add(sub); } System.out.println(res.size()); } }
用一个map来存字符串,暴力匹配时间复杂度n的平方。
当找到第一个字符串后进入循环,这里注意匹配条件,相等或者b[i]为0
#include<bits/stdc++.h>
using namespace std;
int main()
{
unordered_set<string> strMap;
string a, b;
while(cin >> a >> b){
int sizeA = a.size();
int sizeB = b.size();
for(int i = 0;i < sizeA - sizeB + 1;i++)
{
if(a[i] == b[0] || b[0] == '?'){
int cnt = 0;
for(int j = 0;j < sizeB;j++){
if(a[i + j] == b[j] || b[j] == '?')
cnt++;
else
break;
}
if(cnt == sizeB){
strMap.insert(a.substr(i, sizeB));
}
}
}
cout << strMap.size() << endl;
}
return 0;
}
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashSet; /** * @author wylu */ public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); char[] a = br.readLine().toCharArray(); char[] b = br.readLine().toCharArray(); HashSet<String> set = new HashSet<>(); for (int i = 0; i <= a.length - b.length; i++) { StringBuilder sb = new StringBuilder(); for (int j = 0; j < b.length; j++) { if (b[j] == '?' || b[j] == a[i + j]) { sb.append(a[i + j]); } } if (sb.toString().length() == b.length) set.add(sb.toString()); } System.out.println(set.size()); } }
#include <iostream> #include <string> using namespace std; void dfs(string a, string b, int i, int& count) { if(i == b.size()){ // 已经搜索了b字符串的长度,如果当前的字符串在a中,结果就进行自增 if(a.find(b) != string::npos) count ++; return; } if(a.find(b.substr(0, i)) != string::npos){ // 剪枝,保证i之前的字符能够匹配成功 // 位置i的字符未定就进行尝试,否则直接到下一个位置 if(b[i] == '?'){ b[i] = '0'; dfs(a, b, i + 1, count); b[i] = '1'; dfs(a, b, i + 1, count); b[i] = '?'; }else dfs(a, b, i + 1, count); } } int main() { string a, b; cin >> a >> b; int count = 0; dfs(a, b ,0, count); cout << count << endl; return 0; }
#include <bits/stdc++.h> using namespace std; int main(){ string A, B; cin>>A>>B; int n=A.length(), m=B.length(), s=0; if(n<m){ puts("0"); return 0; } vector<string> v; for(int i=0;i<n-m+1;i++){ bool flag = true; for(int j=0;j<m;j++) if(A[i+j]!=B[j] && B[j]!='?') flag = false; if(flag){ string t = A.substr(i, m); if(find(v.begin(), v.end(), t) == v.end()) v.push_back(t); } } printf("%ld\n", v.size()); return 0; }
#include<bits/stdc++.h> using namespace std; int getAns(string a,string b,int num){ if(num == 0) return a.find(b) != -1 ? 1:0; // kmp算法 int i = 0; while(b[i] != '?') ++i; if(a.find(b.substr(0,i)) == -1) return 0; return getAns(a,b.substr(0,i) + "1" + b.substr(i+1),num - 1) + getAns(a,b.substr(0,i) + "0" + b.substr(i+1),num - 1); } int main(){ string a; string b; cin >> a >> b; int num = 0; for(int i = 0;i < b.size();++ i) if(b[i] == '?') ++ num; cout<<getAns(a,b,num)<<endl; }
const readline = require("readline"); const r1 = readline.createInterface({ input: process.stdin, ouput: process.stdout, }); let inArr = []; let temp = []; r1.on("line", (line) => { inArr.push(line.trim()); let a = inArr[0]; let b = inArr[1]; a += ""; b += ""; if (inArr.length > 1) { let index = stringMatch(a, b, 0); while (index < a.length - b.length) { stringMatch(a, b, ++index); } temp = temp.filter((item, index) => temp.indexOf(item) == index); console.log(temp.length); } }); var stringMatch = function (T, P, t) { let p = 0; if (T.length < P.length) return 0; while (t < T.length && p < P.length) { if (T[t] == P[p] || P[p] == "?") { t++; p++; } else { t = t - p + 1; p = 0; } } if (p >= P.length) { temp.push(T.slice(t - p, t - p + P.length)); return t - p; } return 0; };
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { // 输入数据 Scanner in = new Scanner(System.in); String a = in.next(); String b = in.next(); // 算法核心 // 采用HashSet记录匹配成功的字符串,实现去重的目的 HashSet<String> set = new HashSet<>(); int al = a.length(); int bl = b.length(); for (int aStart = 0; aStart < al - bl + 1; aStart++) { // aStart表示新一轮匹配在a上的起点下标,要与b的0位置对齐 boolean yes = true; for (int ai = aStart, bi = 0; bi < bl; ai++, bi++) { // 构造字符匹配成功的条件 boolean match = b.charAt(bi) == '?' || b.charAt(bi) == a.charAt(ai); if (!match) { // 若匹配失败 yes = false; break; } } if (yes) { // 匹配成功时,对应在a上就是aStart ~ aStart + bl - 1上, // 将其记录进set中 set.add(a.substring(aStart, aStart + bl)); } } // 结果输出 System.out.println(set.size()); } }
str1, str2 = input(), input() len1, len2 = len(str1), len(str2) list1 = set() flag = False for i in range(len1-len2+1): substr = str1[i:i+len2] for j in range(len2): if substr[j] != str2[j] and str2[j] != '?': flag = False break else: flag = True if flag == True : list1.add(substr) print(len(list1))
#include<bits/stdc++.h> using namespace std; int main() { string a,b; cin>>a>>b; set<vector<char>> se; for(int i=0;i<=a.length()-b.length();i++) { vector<char> v; int flag=1; for(int j=0;j<b.length();j++) { if(b[j]==a[i+j]) continue; else if(b[j]=='?') v.push_back(a[i+j]); else {flag=0;break;} } if(flag) se.insert(v); } cout<<se.size()<<endl; }移动窗口暴力破解。
let aa=readline(); let bb=readline();let as=new Set(); let l=0;//这里是需要l来记录a的子序列开始位置,这个子序列无论是匹配成功还是匹配失败,下一个子序列的开头都是a的第l+1 for(let i=0,j=0;i<aa.length;){ if(aa[i]==bb[j]||bb[j]=='?'){ j++; if(j==bb.length){ j=0; as.add(aa.slice(l,i+1)); i=l+1; l=i; continue; } }else{ j=0; i=l+1; l=i; continue; } i++ } console.log(as.size);
import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); String a = in.next(); String b = in.next(); HashSet<String> s = new HashSet<>(); for (int i = 0; i < a.length() - b.length() + 1; i++) { int c = 0; for (int j = 0, k = i; j < b.length(); j++, k++) { if (b.charAt(j) == '?' || b.charAt(j) == a.charAt(k)) { //匹配到b串中的字符个数+1 c++; } } //匹配的字符数等于b串长度,说明从第i项开始在a串中完成匹配,将匹配出的存入set if (c == b.length()) { s.add(a.substring(i, i + b.length())); } } System.out.print(s.size()); } }
var count = 0 func main() { var A,B string fmt.Scanf("%s",&A) fmt.Scanf("%s",&B) dfs([]byte(A),[]byte(B),0) fmt.Println(count) } //深度优先超时 func dfs (a,b []byte,i int){ if i == len(b){ if strings.Contains(string(a),string(b)){ count++ } return } if strings.Contains(string(a), string(b[:i+1])){ dfs(a,b,i+1) }else{ if b[i] == '?'{ b[i] = '0' dfs(a,b,i+1) b[i] = '1' dfs(a,b,i+1) b[i] = '?' } } }
package main import "fmt" func stringMatch(a, b string) int { ret := 0 at := []rune(a) bt := []rune(b) res := make(map[string]struct{}) for i := 0; i < len(at)-len(bt)+1; i++ { tmp := 0 for j := 0; j < len(bt); j++ { if at[i+j] == bt[j] || bt[j] == '?' { tmp++ if tmp == len(b) { res[a[i:i+len(b)]] = struct{}{} } } } } ret = len(res) return ret } func main() { a := "" fmt.Scan(&a) b := "" fmt.Scan(&b) ret := stringMatch(a, b) fmt.Println(ret) }
import java.util.*; public class Main{ public static void main(String args[]){ Scanner in = new Scanner(System.in); while(in.hasNext()){ String A = in.nextLine(); String B = in.nextLine(); LinkedHashSet<String> set = new LinkedHashSet(); // 存储可以正确匹配的字符串,最终的set.size()就是匹配种数 for(int i=0;i<=A.length()-B.length();i++){ boolean b = true; for(int j=0,index=i;j<B.length();j++,index++){ if(B.charAt(j)!='?' && B.charAt(j)!=A.charAt(index)){ // B的字符不是?,且对应的字符不相等,则说明不可以匹配 b = false; // 标记不可以匹配 break; } } if(b){ // 可以匹配,添加匹配子串 set.add(A.substring(i,i+B.length())); } } System.out.println(set.size()); } } }