【问题标题】:Finding sequences of characters, whichever's first查找字符序列,以先到者为准
【发布时间】:2023-03-19 05:29:01
【问题描述】:

我写了一个代码,可以找到四种不同的字符序列。

ATG 总是在开始,而 TAG、TGA 或 TAA 是“停止”序列。

START 和 STOP 序列之间的字符数应为 3 的倍数。

例如在以下字符串中:ACCATGCCCTAGTTT 我的程序返回 ATGCCCTAG

在这个字符串中:AAATGCCTAGTTAA程序返回ATGCCTAGT TAA,因为 ATG 和 TGA 之间的字符数不是三的倍数,所以它寻找下一个“停止”序列,在这种情况下是 TAA。

代码如下:

public class TagFinder {
    public String findProtein(String dna) {
        String fpL = dna.toLowerCase();
        int start = fpL.indexOf("atg");
        int stop = fpL.indexOf("tag", start+3);
        int stop2 = fpL.indexOf("tga", start+3);
        int stop3 = fpL.indexOf("taa", start+3);
        if (start == -1) {
            return "";
        }

        if ((stop - start) % 3 == 0) {
            return fpL.substring(start, stop+3);
        }

        if ((stop2 - start) % 3 == 0) {
            return fpL.substring(start, stop2+3);
        }

        if ((stop3 - start) % 3 == 0) {
            return fpL.substring(start, stop3+3);
        }
        else {
            return "";
        }
    }

但是,在下面的字符串“ATTATGCCCTAATAG”中,代码​​会首先找到ATGCCCTAATAG,即使 TAA 是字符串中的第一个“停止”序列,并且 ATG 和 TAA 之间的字符数是 3。

我如何编写这个程序,以便返回字符串中最先出现且距离起始序列 n3 的“STOP”序列。

谢谢。

【问题讨论】:

    标签: java string


    【解决方案1】:

    正则表达式就可以了。

        String input = "ACCATGCCCTAGTTT";
        String expected = "ATGCCCTAG";
    
        Pattern pattern = Pattern.compile("(ATG)(.{3})*?(TAG|TGA|TAA)",
                Pattern.CASE_INSENSITIVE);
        Matcher m = pattern.matcher(input);
        while (m.find()) {
            System.out.printf("[%d] %s%n", m.start(), m.group());
        }
    

    上面的起始位置不一定是3的倍数。如果起始位置必须是3的倍数,那么最容易将3个字母和一个分隔符组成组。

        input = input.replaceAll(".{3}", "$0,");
    
        Pattern pattern = Pattern.compile("(ATG,)(.{4})*?(TAG|TGA|TAA),",
                Pattern.CASE_INSENSITIVE);
        Matcher m = pattern.matcher(input);
        while (m.find()) {
            System.out.printf("[%d] %s%n", m.start() * 3 / 4, m.group().replace(",", ""));
        }
    

    【讨论】:

      【解决方案2】:

      你需要确定所有停止标签的最小值,所以我会这样写:

          [...]
          int minStop = MAXINT;
      
          if ((stop - start) % 3 == 0 && minStop > stop) {
              minStop = stop;
          }
      
          if ((stop2 - start) % 3 == 0 && minStop > stop2) {
              minStop = stop2;
          }
      
          if ((stop3 - start) % 3 == 0 && minStop > stop3) {
              minStop = stop3;
          }
      
          if (minStop < MAXINT) {
              return fpL.substring(start, minStop+3);
          } else {
            [...]
          }
      

      【讨论】:

        【解决方案3】:

        来自

        if ((stop - start) % 3 == 0) { return fpL.substring(start, stop+3); }

        它首先找到 TAG 并调用 return 语句。如果你真的想找到第一个停止点,可以在stopstop2stop3 之间添加一些比较逻辑来找到最小的索引。然后对每个进行% 3 检查并从第一个正常的返回,或者如果没有有效的大小写则返回整个字符串。另外如何使用正则表达式来解决这个问题? (ATG)\w{3}(TAG|TGA|TAA) 中的内容。

        【讨论】:

          【解决方案4】:

          以下代码使用任何搜索词的列表,然后选择最小匹配索引。

          public String findProtein(String dna) {
              String fpL = dna.toLowerCase();
              int start = fpL.indexOf("atg");
          
              List<String> searchWords = new ArrayList<>();
              searchWords.add("tag");
              searchWords.add("tga");
              searchWords.add("taa");
          
              int start = fpL.indexOf("atg");
              try{
                  int startIndex = searchWords.stream().mapToInt(word -> fpL.indexOf(word, 3 + start)).filter(idx -> idx >= 0 && 0 == idx % 3)
                          .min().getAsInt();
          
                  return dna.substring(start, startIndex + 3);
          
              } catch(NoSuchElementException ex) {
                  return "";
              }
          }
          

          【讨论】:

            【解决方案5】:

            代码首先找到“TAG”的原因是因为您编写代码的方式: 您的第一个 if 语句会检查“TAG”。如果找到,则返回“ATG”和“TAG”之间的字符串并终止。

            您需要做的是创建一个min 变量并将找到的终止密码子的值存储在这个min 中(在检查它确实是最小值之后)。不要在搜索终止密码子的if 语句中使用return。并仅在执行三个 if 语句并确定与“TAG”的实际最小距离后才返回 min + 3

            希望有用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-01-24
              • 1970-01-01
              • 1970-01-01
              • 2019-07-13
              • 2015-04-30
              • 2016-01-29
              • 2011-09-20
              • 1970-01-01
              相关资源
              最近更新 更多