- 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/
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!