在Java中查找字符串模式

时间:2015-01-16 19:48:43

标签: java arrays string sequence

我想在以下字符串中找到一个模式:

NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTCNATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGGGGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGNNGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNNCNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGGNTGNNNNNNNNNNNNNNNNNNNNNNNNNNN

模式必须包含至少4个相邻字符,“N”除外。

例如,在此字符串中,

NNNNNTTCAANGGGACGG.....

我可以获得“TTCA”“TCAA”“GGGA”,“GGAC”,“GACG”,“ACGG”......

我想找到任何与该模式匹配的字符串。

哪种方法最适合这个?

我可以创建一个数组并读取每个字符。 但是,有没有更好的设计和想法?

谢谢!

3 个答案:

答案 0 :(得分:2)

一种方法是使用Java 8 Stream进行一些过滤,映射和收集:

String str = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTCAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTCNATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGGGGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGNNGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNNCNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGGNTGNNNNNNNNNNNNNNNNNNNNNNNNNN";
final char[] src = str.toCharArray();

final int len = 4;
final int ch = 'N';
final List<String> collect =
        IntStream.range(0, str.length() - len)
                .filter(offset -> IntStream
                        .range(offset, offset + len)
                        .noneMatch(i -> src[i] == ch))
                .boxed()
                .map(i -> str.substring(i, i + len))
                .collect(Collectors.toList());

System.out.println(collect); // [TTCA, TCAA, GGGA, GGAC, ....

答案 1 :(得分:1)

您可以使用PatternMatcher来完成此操作。使用Matcher#find(int index),您可以从指定的索引开始匹配。给定的Pattern匹配,Matcher重置为从上一个匹配位置+ 1开始,因此不会丢失子字符串。

<强>代码

public static void main(String[] arguments) throws FileNotFoundException {
    Matcher m = Pattern.compile("[A-M|O-Z]{4}").matcher(
            "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTT"
                    + "CAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTC"
                    + "NATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGG"
                    + "GGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGN"
                    + "NGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNN"
                    + "CNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGG"
                    + "NTGNNNNNNNNNNNNNNNNNNNNNNNNNNN");

    int index = 0;
    while (m.find(index)) {
        index = m.start() + 1;
        System.out.println(m.group());
    }
}

<强>输出

TTCA
TCAA
GGGA
GGAC
GACG
ACGG
CGGA
GGAG
GAGC
AGCG
GCGG
CGGG
GGGT
GGTG
GTGC
GAGG
AGGA
GGAG
GCGC
CGCT
GCTT
CTTC
TTCG
TCGA
CGAC
GACA
ACAG
CAGC
AGCG
GCGA
CGAC
GACG
ACGT
CGTG
GTGG
TGGG
GGGG
GGGG
GGGA
GGAG
GAGT
GGCG
GCGG
CGGT
GGTG
GTGA
TGAC
GAGC
AGCT
GGGC
GGCG
GCGG
CGGC
GGCC
GCCT
CTGG
TGGA
GGAA
GAAC
AACA
ACAG
CAGC
AGCC
GCCA
CCAG
CAGA
AGAA
GAAG
AAGG
AGGA
GGAC
TCCT
CCTG
CTGG
TGGA
GTGG
TGGA
GGAC
GACA
TGCA
GCAG
CAGA
AGAC
GACA
ACAC
CACA
ACAA
CAAC
AACT
ACTA
CTAC
TACG
ACGG
CGGG
GGGG

答案 2 :(得分:1)

这是我的正则表达过敏解决方案。感谢@Niels Billen提供了很好的源字符串格式。

public static void main(String[] args) {
     String string =  "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTT"
                        + "CAANGGGACGGAGCGGGTGCNGTNNCNGGANAGANNCNTC"
                        + "NATNANCNNGAGGAGNNCNNGCGCTTCGACAGCGACGTGG"
                        + "GGGAGTNCNNGGCGGTGACNGAGCTNGGGCGGCCTNNNGN"
                        + "NGAGNNCTGGAACAGCCAGAAGGACNTCCTGGANNNNNNN"
                        + "CNNGNCNNNGTGGACANNNNNTGCAGACACAACTACGGGG"
                        + "NTGNNNNNNNNNNNNNNNNNNNNNNNNNNN";

     for (String s: string.split("N")) {
         for (int i = 0 ; i <= s.length() - 4 ; i++) {
             System.out.println(s.substring(i, i + 4));
         }
     }
}