我对一个问题很难过。
这个问题需要一个缺少字母的线索。有一系列单词要与线索匹配,但是,如果单词中没有来自线索的字母,则该单词应该匹配。
我正在使用正则表达式,它匹配匹配的所有实例,但我无法弄清楚如何排除单词中包含重复字母的那些 名单。
例如,线索是aba???
因此,abaton
应该匹配,但abatua
不应该匹配,因为两个单词中都有a
,而且线索部分被掩盖了???
这是我的代码:
import java.util.ArrayList;
public class MatchTest {
public ArrayList<String> wordLookup(ArrayList<String> wordList, String clue) {
ArrayList<String> arrayList = new ArrayList<>();
String regex = clue.replaceAll("\\?", "\\.?");
for (int i = 0; i < wordList.size(); i++) {
if (wordList.get(i).matches(regex)) {
arrayList.add(wordList.get(i));
}
}
return arrayList;
}
}
class MatchTestMain {
public static void main(String[] args) {
MatchTest mt = new MatchTest();
ArrayList<String> wordList = new ArrayList<String>();
wordList.add("abandon");
wordList.add("wanton");
wordList.add("abaton");
wordList.add("abator");
wordList.add("abatua");
System.out.println(mt.wordLookup(wordList, "aba???"));
}
}
我收到了这个输出
[abaton, abator, abatua]
但正确的输出是
[abaton, abator]
有什么想法吗?
编辑完整性:我找到了一个边缘情况,其中线索是全部?例如,线索是??????,它会导致线程“main”中的异常java.util.regex.PatternSyntaxException:Unclosed character [^]
我扩展了@Malte Hartwig提出的解决边缘案例的解决方案。
以下是最终版本:
import java.util.ArrayList;
public class MatchTest {
public ArrayList<String> wordLookup(ArrayList<String> wordList, String clue) {
ArrayList<String> arrayList = new ArrayList<>();
String givenLetters = clue.replaceAll("\\?", "");
String regex = clue.replaceAll("\\?", "\\[^" + givenLetters + "]");
String regex2 = clue.replaceAll("\\?", "\\.?");
if (givenLetters.length() == 0) {
for (int i = 0; i < wordList.size(); i++) {
if (wordList.get(i).matches(regex2) && wordList.get(i).length() == clue.length()) {
arrayList.add(wordList.get(i));
}
}
}
if (givenLetters.length() > 0) {
for (int i = 0; i < wordList.size(); i++) {
if (wordList.get(i).matches(regex)) {
arrayList.add(wordList.get(i));
}
}
}
return arrayList;
}
}
class MatchTestMain {
public static void main(String[] args) {
MatchTest mt = new MatchTest();
ArrayList<String> wordList = new ArrayList<>();
wordList.add("abandon");
wordList.add("wanton");
wordList.add("abaton");
wordList.add("abator");
wordList.add("abatua");
System.out.println(mt.wordLookup(wordList, "ab??o?"));
System.out.println(mt.wordLookup(wordList, "?b????"));
System.out.println(mt.wordLookup(wordList, "abatua"));
System.out.println(mt.wordLookup(wordList, "a?a???"));
System.out.println(mt.wordLookup(wordList, "?ridge"));
System.out.println(mt.wordLookup(wordList, "aba???"));
System.out.println(mt.wordLookup(wordList, "??????"));
}
}
输出:
[]
[abaton, abator, abatua]
[abatua]
[abaton, abator]
[]
[abaton, abator]
[wanton, abaton, abator, abatua]
答案 0 :(得分:2)
您可以先提取线索中给出的字母列表:
String givenLetters = clue.replaceAll("\\?", "");
// givenLetters = "aba"
如果您在正则表达式中使用该列表,则可以将掩盖的字符不告知其中一个字母:
String regex = clue.replaceAll("\\?", "\\[^" + givenLetters + "]");
// regex = "aba[^aba][^aba][^aba]";
这会在您的示例中替换.?
[^aba]
,意思是&#34;不是a
或b
&#34; (或a
,在这种情况下无关紧要)。
它也应该适用于最后不只有?
的线索,例如??a?b?
,这会导致pattern = [^ab][^ab]a[^ab]b[^ab]
。
答案 1 :(得分:-1)
在您的程序中进行了一些更改...正在提供所需的输出
package testProgram;
import java.util.ArrayList;
class MatchTest {
public ArrayList<String> wordLookup(ArrayList<String> wordList, String clue) {
ArrayList<String> arrayList = new ArrayList<>();
// String regex = clue.replaceAll("\\?", "\\.?");
for (int i = 0; i < wordList.size(); i++) {
if (wordList.get(i).matches(clue)) {
arrayList.add(wordList.get(i));
}
}
return arrayList;
}
}
public class MatchTestMain {
public static void main(String[] args) {
MatchTest mt = new MatchTest();
ArrayList<String> wordList = new ArrayList<String>();
wordList.add("abandon");
wordList.add("wanton");
wordList.add("abaton");
wordList.add("abator");
wordList.add("abatua");
System.out.println(mt.wordLookup(wordList, "(aba)[^aba]{0,3}"));
}
}
(aba)[^ aba] {0,3}表示前3个字符将保持不变(aba)休息0-3个字符不包含这3个中的任何字符,即(aba)。
{0,3}表示至少为0且最多为3个字符。