1

已编辑

我有这种字符串

  1. "A-B-C-D"
  2. "B-C-A"
  3. "D-A"
  4. "B-A-D"
  5. "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 个数据,我不想使用尽可能多的循环。

4

4 回答 4

3

这可能会根据您是否需要与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
于 2013-08-14T03:57:09.603 回答
2

使用一个数组并遍历每个索引,看看它是否包含“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);
      }
于 2013-08-14T03:34:18.170 回答
1

在您要检查的每个字符串上调用此函数。如果它返回 true,则将该字符串添加到您的结果集中。

boolean matches(String s, char[] chars) {
    for(char c : chars) {
        if (s.indexOf(c) == -1) {
            return false;
        }
    }
    return true;
}
于 2013-08-14T03:49:29.240 回答
1

编辑:这适用于旧版本的 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. 我希望你自己做,但我会提供一个算法作为提示:

  1. 从 searchIn 和 searchFor 的开头开始。
  2. 一次通过 searchIn 一个元素。
  3. 当在 searchIn 中找到 searchFor 的当前元素时,将 searchFor 推进到下一个元素。
  4. 如果你点击了 searchFor 的结尾,你就找到了这个序列。
  5. 如果您点击了 searchIn 的结尾而不是 searchFor,则序列不匹配。

现在您可以检查一个序列是否以任何顺序包含另一个序列。要将其应用于您的整个集合,我建议List<String>在开始时将所有字符串解析为一次,然后您可以使用上述算法遍历每个字符串。

有许多替代选择。例如,您可以使用indexOfonsearchIn查找其中的每个元素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 */;

请注意,这个特定的正则表达式解决方案假定每个元素只有一个字符长。

此外,上述两种方法都假设区分大小写匹配——为了使第一个不区分大小写,我只需在解析之前将字符串转换为小写即可。对于第二个,您可以使用不区分大小写的正则表达式。

希望有帮助。如果需要,请在一张纸上解决。

这里的一般要点是它有助于首先将这些问题减少到最小的组件。

于 2013-08-14T03:59:05.387 回答