- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有多个通配符表达式,例如:
*a*b*
*c*d*
*e*?*
哪里
*
表示0个或多个字母(可以是任意字母,不一定相同)?
表示任何一次出现信我需要找到与这些通配符模式匹配的最短字符串。例如在上面的示例中,这些字符串之一是:
abced
还有另一个例子:
?a*b
a*b*
*a??a*
结果将是
aa?ab -> meaning "aaaab" OR "aabab" OR ...
我想我需要在这里使用动态规划。尝试了一些方法,但只得到了部分结果。有什么想法吗?
最佳答案
适用于较小的示例。对于较大的,需要太多时间。也许是因为我使用数组计算转换。
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
public class Safe {
public static void main(String[] args) {
String[] patterns = new String[3];
patterns[0] = "?a*b";
patterns[1] = "a*b*";
patterns[2] = "*a??a*";
String sol = new Safe().solution(patterns);
System.out.println(sol);
if(!sol.equals("aabab")){
throw new RuntimeException("Not Equal!");
}
patterns = new String[3];
patterns[0] = "*a*b*";
patterns[1] = "*c*d*";
patterns[2] = "*e*f*";
System.out.println(new Safe().solution(patterns));
patterns = new String[3];
patterns[0] = "*p?qp?*bd*pd?q*";
patterns[1] = "*qp*d?b*?p?d*";
patterns[2] = "?*d?b???q*q?p*";
sol = new Safe().solution(patterns);
System.out.println(sol);
if(!sol.equals("p?qpd?bdpdqqppd")){
throw new RuntimeException("Not Equal!");
}
patterns = new String[2];
patterns[0] = "*z*y*y*z*x*x*x*z*x*z*y*z*y*x*x*y*y*y*z*x*y*z*y*x*x*x*z*x*z*z*z*y*y*z*x*y*z*";
patterns[1] = "*y*z*z*x*x*y*z*y*z*y*x*z*y*z*y*x*z*y*x*y*x*y*y*z*x*y*z*x*x*z*y*z*y*y*x*z*y*";
sol = new Safe().solution(patterns);
System.out.println(sol);
if(!sol.equals("yzyyzxxyzyxzyxzyzyxzyxyxyyzxyzyxxxzyxzzzyyxzxyz")){
throw new RuntimeException("Not Equal!");
}
}
private boolean isItLetter(char c) {
return c != '*' && c != '?';
}
private char match(String[] patterns, int[] indices) {
boolean firstThrown = true;
try {
char matched = '*';
for (int i = 0; i < patterns.length; i++) {
char c = patterns[i].charAt(indices[i]);
firstThrown = false;
if (isItLetter(c)) {
if (isItLetter(matched)) {
if (matched != c) {
//two different letters
//so we cannot continue
return Character.MIN_VALUE;
}
}
matched = c;
} else {
//* or ?
if (!isItLetter(matched)) {
//so we do not overwrite ? with *
if (c == '?') {
matched = c;
}
}
}
}
return matched;
} catch (StringIndexOutOfBoundsException e) {
//means we tried matching end of string
//check if all are at the end
if (firstThrown) {
//check only if first thrown;
//otherwise, one of patterns is not at the end
for (int i = 1; i < patterns.length; i++) {
if (indices[i] < patterns[i].length()) {
return Character.MIN_VALUE;
}
}
} else {
return Character.MIN_VALUE;
}
//max when we reached the end
return Character.MAX_VALUE;
}
}
class Node{
final String recognized;
final int[] indices;
public Node(String recognized, int[] indices) {
this.recognized = recognized;
this.indices = indices;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return recognized.equals(node.recognized) &&
Arrays.equals(indices, node.indices);
}
@Override
public int hashCode() {
int result = Objects.hash(recognized);
result = 31 * result + Arrays.hashCode(indices);
return result;
}
}
Queue<Node> queue = new ArrayDeque<>();
Set<Node> knownStates = new HashSet<>();
public String solution(String[] patterns){
List<int[]> startingIndices = generateStartingIndices(patterns, new int[patterns.length]);
for(int[] si : startingIndices){
Node nextNode = new Node("", si);
queue.offer(nextNode);
}
String result = null;
while (result == null) {
result = solution(patterns, queue.poll());
}
return result;
}
private List<int[]> generateStartingIndices(String[] patterns, int[] indices){
List<int[]> generated = Collections.singletonList(new int[patterns.length]);
for(int i=0; i<patterns.length; i++){
char currentChar = patterns[i].charAt(indices[i]);
List<int[]> replaceGenerated = new ArrayList<>();
if(currentChar == '*'){
for(int[] gi : generated){
gi[i] = indices[i]+1;
replaceGenerated.add(gi);
}
for(int[] gi : generated){
int[] gin = gi.clone();
gin[i] = indices[i];
replaceGenerated.add(gin);
}
}
else{
for(int[] gi : generated){
gi[i] = indices[i];
replaceGenerated.add(gi);
}
}
generated = replaceGenerated;
}
return generated;
}
private List<int[]> generateNextIndices(String[] patterns, int[] indices){
List<int[]> generated = Collections.singletonList(new int[patterns.length]);
for(int i=0; i<patterns.length; i++){
char currentChar = patterns[i].charAt(indices[i]);
char nextChar = Character.MIN_VALUE;
if(indices[i]+1 < patterns[i].length()){
nextChar = patterns[i].charAt(indices[i]+1);
}
List<int[]> replaceGenerated = new ArrayList<>();
if(currentChar == '*'){
//or next index
for(int[] gi : generated){
gi[i] = indices[i]+1; //short it first so we first test that case
replaceGenerated.add(gi);
}
//same index or
for(int[] gi : generated){
int[] gin = gi.clone();
gin[i] = indices[i];
replaceGenerated.add(gin);
}
}
else{
//some character
if(nextChar=='*'){
//or if * we can skip
for(int[] gi : generated){
gi[i] = indices[i]+2; //skip first so we check that shorter case
replaceGenerated.add(gi);
}
}
//we can go next or
for(int[] gi : generated){
int[] gin = gi.clone();
gin[i] = indices[i]+1;
replaceGenerated.add(gin);
}
}
generated = replaceGenerated;
}
return generated;
}
public String solution(String[] patterns, Node node) {
char matched = match(patterns, node.indices);
if (matched == Character.MAX_VALUE) {
//we reached the end
return node.recognized;
}
if (matched == Character.MIN_VALUE) {
//impossible to match
return null;
}
if(matched == '*'){
//all stars
return null;
}
List<int[]> nextIndices = generateNextIndices(patterns, node.indices);
for(int[] ni : nextIndices){
Node nextNode = new Node(node.recognized + matched, ni);
if(notKnownState(nextNode)) {
queue.offer(nextNode);
}
}
return null;
}
private boolean notKnownState(Node node) {
if(knownStates.contains(node)){
return false;
}
knownStates.add(node);
return true;
}
}
关于java - 匹配多个通配符表达式的最短字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60084955/
我的网址看起来像 '/api/comments/languages/124/component/segment_translation/2' 我知道 url 的哪些部分是静态的;并且是动态的 - 并且
如何使用通配符查找和替换主域之后的所有字符(包括“/”字符)? 例如,我有以下 4 行: intersport-schaeftlmaier.de/ weymouthhondapowersports.c
我有 3 个控件,其 ID 为 control_1、control_2、control_3。 我想隐藏这些控件。 目前我正在使用这个: $('#control_1').hide(); $('#cont
我有一个旧歌曲数据库,我想将其转移到新数据库。我的旧数据库看起来像这样,多个值被填充在一个用逗号分隔的字段中 SONG id | title | artist |
首先,我知道downloads表没有标准化。 我有这两个表: downloads map | author 1 | Nikola 2 | Nikola George 和 mappers mapper_
通配符可用于替代字符串中的任何其他字符。 SQL 通配符 在 SQL 中,通配符与 SQL LIKE 操作符一起使用。 SQL 通配符用于搜索表中的数据。 在 SQL 中,可使用以下通配符:
我在 shell 脚本中有一行看起来像这样: java -jar "$dir/"*.jar ,因为我只想执行该文件夹中恰好命名的 jar 文件。但这并不像我预期的那样有效。我收到错误消息: Error
我想在 Active Directory 用户的所有属性中搜索特定电话号码/分机号。 我可以像这样获取所有属性: get-aduser joesmith -Properties * 但我想过滤结果,例
我在运行 Python 3在 Windows 机器上使用 PowerShell .我正在尝试执行一个 Python 文件,然后使用通配符将多个文件(file1.html、file2.html 等)作为
我有一个 div,并且有一些处于未定义级别的子节点。 现在我必须将每个元素的 ID 更改为一个 div。如何实现? 我想,因为它们有向上的ID,所以如果父级是id='path_test_maindiv
我是 Lua 的新手,所以我现在正在学习运算符部分。在 Lua 中是否有与字符串一起使用的通配符? 我有 PHP 背景,我实际上是在尝试编写以下代码: --scan the directory's f
我在 countList 方法上遇到编译时错误。 public static void countList( List list, int count ){ for( int i =
我们需要在运行时检索多个类实例,而无需手动维护所有可用类型的列表。 可能的方法: 检索带有@xy注释的每种类型的实例 检索每种类型的实例实现接口(interface)iXY 检索每种类型的实例,命名如
我目前陷入了序言问题。 到目前为止我有: film(Title) :- movie(Title,_,_).(其中“movie(T,_,_,)”是对我的引用数据库) namesearch(Title,
我想从字符表达式(在 R 中)中删除一个“*”。在阅读帮助页面并尝试谷歌后,我无法充分理解 gsub 的复杂性。有人可以建议我该怎么做吗? 谢谢, 乔纳森。 最佳答案 您需要转义两次:一次针对 R,一
在我的 DOM 中,我有一个动态生成对话框的表。 DOM 中的对话框将具有以下形式的 ID: id="page:form:0:dlg" id="page:form:1:dlg" id="page:fo
我是 Java 新手,并且已经陷入这样一种情况,很明显我误解了它如何处理泛型,但是阅读教程和搜索 stackoverflow 并没有(至少到目前为止)让我清楚我怀疑我滥用了通配符。需要注意的是,我有
我想使用 jQuery 更改单击时图像的 src 属性。这是 HTML: View 2 在 img src 中,我想将“a”替换为“b”,但我的问题是我想忽略它前面的“1”,因为它也可能看起来像这样
我有一个 mysql 数据库,我的表是: Name | passcode ---------------------- hi* | 1111 ------------------
我想选择所有在星号所在位置具有确切 4 个“未知”字符的文档:(例如“****”可能是“2018”) foreach (string s in Directory.GetFiles(@"C:\User
我是一名优秀的程序员,十分优秀!