【发布时间】:2020-09-04 00:32:14
【问题描述】:
所以我的问题是:
我有一个包含 N 个小写字母字符串的列表,每个字符串的长度为 M。我们称之为 S
例如:对于 m=3 {aab,aac,aba,abc,bab,bac,bba}
然后我有 Q 查询字符串,它也有长度 m 并且包含小写字符和'?'。
对于每个查询字符串,返回匹配查询字符串的字符串计数。
注意:'?'等于任何字符。
示例:
对于查询字符串 'a?b' answer=1, {aab}
查询字符串'a??' answer=4, {aab,aac,aba,abc} 等。
到目前为止我做了什么
蛮力
for each query q:
count=0
iterate over the list of String in s:S
if q.charAt(i) != '?' || s.charAt(i) != q.charAt(i)
flag=false;
break;
if flag==true
count+=1
print count
时间:O( Q * N * M )
我想出了另一种使用二分搜索的方法:
- 对字符串列表进行排序。
- 将字符串列表视为 N * M 个字符的网格
- 对于每个查询字符串,而不是匹配列表中的每个字符串,递归地逐个字符地匹配。
- 当字符匹配时,只考虑匹配的字符串集。例如:对于位置 pos 的字符,如果 Grid[l][pos] 到 Grid[r][pos] 匹配,则将 Grid 的这个子集传递给递归调用。
- 如果 pos 处的字符是 '?'然后将 [a...z] 中的值分配给字符并求解该位置的每个值。
伪代码:
function: (l,r) binarySearch(List, ch, start, end);
function recursion(List, query, pos, start, end)
result=0
if query.charAt(pos) != '?'
(l,r) binarySearch(List, query.charAt(pos), start, end)
if pos = query.length:
return length(l,r)
if (l,r) not empty:
result += recursion(List, query, pos+1, l, r)
else
if pos = query.length
return length(start,end)
for ch in [a...z]
(l,r) binarySearch(List, ch, start, end)
if (l,r) not empty:
result+=recursion(List, query, pos+1, l, r)
return result
function doSomething(List, Query)
List : sort the list alphabetically
for each query in Query:
ans = recursion(List, query, 0, 0, N)
最坏的情况:
如果所有查询字符串都是 [???, ???, ??? ...] 那么结果是 O( Q * N * M )。 尽管如此,这看起来还是比蛮力更好的解决方案。
我仍然觉得我们是否可以事先预处理列表并在更短的时间内回答 Q 查询。我无法弄清楚预处理的逻辑,以便查询将花费更少的时间。 任何帮助表示赞赏。
【问题讨论】:
-
我没有阅读全文,但这篇文章可能会对您有所帮助:stackoverflow.com/questions/7067161/…
标签: java string algorithm data-structures string-matching