已编辑
我有这种字符串
"A-B-C-D"
"B-C-A"
"D-A"
"B-A-D"
"D-A-B-C"
现在我的问题是,如果用户输入的值"A-C"
或"C-A"
数字 1,2,5 将是我的输出,因为这些数字的值是“AC”,例如,如果用户的输入值是这三个中的任何"A-B-D"
一个"B-A-D"
,,,"A-D-B"
输出将是 1,4,5。希望它能解决问题
注意: 搜索顺序取决于用户输入,我希望它更有效,因为我有 10,000 个数据,我不想使用尽可能多的循环。
这可能会根据您是否需要与String
您拥有的确切模式而改变,但真的很简单......
public class Simple {
public static void main(String[] args) {
System.out.println("1. " + matches("A-B-C-D"));
System.out.println("2. " + matches("B-C-A"));
System.out.println("3. " + matches("D-A"));
System.out.println("4. " + matches("B-A-D"));
System.out.println("5. " + matches("D-A-B-C"));
}
public static boolean matches(String value) {
return value.contains("A") && value.contains("C");
}
}
哪个输出
1. true
2. true
3. false
4. false
5. true
使用变量匹配器的扩展示例
因此,基本思想是提供某种要匹配的值列表。这个例子简单地使用了一个String
可变参数(或String
数组),但让它使用类似的东西并不难List
public class Simple {
public static void main(String[] args) {
String[] match = new String[]{"A", "D", "C"};
System.out.println("1. " + matches("A-B-C-D", match));
System.out.println("2. " + matches("B-C-A", match));
System.out.println("3. " + matches("D-A", match));
System.out.println("4. " + matches("B-A-D", match));
System.out.println("5. " + matches("D-A-B-C", match));
}
public static boolean matches(String value, String... matches) {
boolean doesMatch = true;
for (String match : matches) {
if (!value.contains(match)) {
doesMatch = false;
break;
}
}
return doesMatch;
}
}
这输出...
1. true
2. false
3. false
4. false
5. true
使用一个数组并遍历每个索引,看看它是否包含“CA”或“AC”,然后是否打印数字。
String stringArray[] = {"A-B-C-D", "B-C-A", "D-A", "B-A-D", "D-A-B-C"};
for(int i = 0; i < stringArray.length; i++) {
String pattern = ".*C-.*A.*";
String pattern2 = ".*A-.*C.*";
if(stringArray[i].matches(pattern) || stringArray[i].matches(pattern2))
System.out.println(i + 1);
}
在您要检查的每个字符串上调用此函数。如果它返回 true,则将该字符串添加到您的结果集中。
boolean matches(String s, char[] chars) {
for(char c : chars) {
if (s.indexOf(c) == -1) {
return false;
}
}
return true;
}
编辑:这适用于旧版本的 OP,它不清楚如何按顺序查找序列;所以这会按顺序搜索序列,现在是不正确的。
有很多选择。下面我概述了一种首先对字符串进行标记的方法,以及另一种使用从输入字符串生成的简单正则表达式的方法。
方法一:解析字符串
首先将每个解析String
为一个子字符串数组,这将使这一切更容易使用。您可能希望在最初阅读它们时解析每个字符串,而不是每次需要时:
String myString = "A-B-C-D";
String[] sequence = myString.split("-");
接下来,考虑使用 aList<String>
而不是 a String[]
,因为它会使其余部分变得更容易(你会看到)。所以,而不是上面的:
String myString = "A-B-C-D";
List<String> sequence = Arrays.asList(myString.split("-"));
现在问题变成了检查其中两个数组是否匹配:
public static boolean containsSequence (List<String> searchIn, List<String> searchFor) {
}
您需要检查两个方向,但您可以简单地反转数组并将此问题进一步减少为仅检查正向(当然有方法可以做到这一点并避免复制,但它们可能会变得复杂,只有当您有时才值得高性能要求):
public static boolean containsSequence (List<String> searchIn, List<String> searchFor) {
// first check forward
if (containsSequenceForward(searchIn, searchFor))
return true;
// now check in reverse
List<String> reversedSearchFor = new ArrayList<String>(searchFor);
Collections.reverse(reversedSearchFor);
return containsSequenceForward(searchIn, reversedSearchFor);
}
public static boolean containsSequenceForward (List<String> searchIn, List<String> searchFor) {
}
// usage example:
public static void example () {
List<String> searchIn = Arrays.asList("D-A-B-C".split("-"));
List<String> searchFor = Arrays.asList("A-C".split("-"));
boolean contained = containsSequence(searchIn, searchFor);
}
现在你只需要实现containsSequenceForward
. 我希望你自己做,但我会提供一个算法作为提示:
现在您可以检查一个序列是否以任何顺序包含另一个序列。要将其应用于您的整个集合,我建议List<String>
在开始时将所有字符串解析为一次,然后您可以使用上述算法遍历每个字符串。
有许多替代选择。例如,您可以使用indexOf
onsearchIn
查找其中的每个元素searchFor
并确保索引按递增顺序排列。
方法 2:正则表达式
这里的另一个选项是使用正则表达式在源字符串中查找搜索序列。您可以很容易地从搜索序列中动态构建正则表达式:
String searchIn = "D-C-B-A";
String searchFor = "C-A";
String searchForPattern = searchFor.replace("-", ".*"); // yields "C.*A"
if (searchIn.matches(".*" + searchForPattern + ".*"))
/* then it matches forwards */;
然后反向匹配,如果正向匹配失败,你可以反向searchFor
重复:
String searchForReverse = new StringBuilder(searchFor).reverse().toString();
String searchForReversePattern = searchForReverse.replace("-", ".*"); // yields "A.*C"
if (searchIn.matches(".*" + searchForReversePattern + ".*"))
/* then it matches backwards */;
请注意,这个特定的正则表达式解决方案假定每个元素只有一个字符长。
此外,上述两种方法都假设区分大小写匹配——为了使第一个不区分大小写,我只需在解析之前将字符串转换为小写即可。对于第二个,您可以使用不区分大小写的正则表达式。
希望有帮助。如果需要,请在一张纸上解决。
这里的一般要点是它有助于首先将这些问题减少到最小的组件。