我的信很少,想找到经常发生的模式。
我有以下信件:
---------TAAA-GAGAG----T--T-------T
-------------T------A---------T----
----------AAA-GAGAG---C-----------T
------C------------T-A----T-----TA-
-----AC----------------TT--------C-
-------------------T---------------
---A---------------T---------------
-------------------------T----T----
------C---------------------T-----T
----------AAA-GAGAG---C------------
----A--------------------T-------A-
--------G-G-----------G-------T----
----A--------------------T---------
---------T-------------------------
-----AC------T--------------------T
--GA-G------------GT--------------T
-----A--G-AAA-GAGAG-AA-------------
-----------------------------------
-T-------C-G-------T---TT------T--T
TT-----------------T---------------
-------------------T---TT-T--------
---A----G------------A--------T----
-----------------------------------
-------T--AA--G-GAG---C------------
-T-A----------------A--------------
------------T------------------T---
-----------G-----------------------
--G-A------------------C---T---T---
----A---G---A-------A------T-------
--------G-------------------T-----T
-TG--------A---------A-T-----------
--G--A--------GAGAG---CT-----------
---A-------G------------T----G---A-
T-------G----T---------------------
-T----C-GCAA--GAGAG-A-C-----T--TT--
-----A----AAA-GAGAG-A-T------G---A-
-T---------G-----------------------
---A---T---------------------G-----
---A---------T-------A---T---A---A-
-----------------------------------
TC--A----T----------G-------T-T--G-
-T----CT---G-T-----T-A----T-T--T---
-------------T-----TA------------A-
--G----T-----------------T-T--T----
---A------AA--GAGAG---C-----T------
--------------GAGAG-A-C------------
----------AA--GAGAG---C-G----------
正如您所看到的,中间有一个模式:" GAGAG",所以我可以说G + A + G + A + G来自相同的数据。
我想拆分那些行和组。
错误的案例。第一行有T + A + A + A但另一行不与 T + A + A + A,只有A + A + A总是在一起。所以在这种情况下,T和A不是组。
任何人都知道这种相关算法或如何找到模式。
我尝试使用Java编程。
谢谢。
更新-----------------------------------------
1)模式需要的最小长度是多少? - 两个。并且不必是连续的职位。
2)可以" - "符号是模式的一部分? - 不。" - "意味着这个位置可以是任何字符,例如" undefined"。
3)模式应该位于每条线的完全相同的索引上吗? - 是(但有些行可能是 - )
4)模式发生的最小数量是多少(2个出现的次数是多少?) - 这还没有确定,只是想先找到最多的出现位置,以后会发现最佳出现位置。
答案 0 :(得分:2)
您可以创建https://en.wikipedia.org/wiki/Suffix_array和https://en.wikipedia.org/wiki/LCP_array并查看最不常用的前缀数组以查找长公共前缀,这意味着再次出现了子字符串。
答案 1 :(得分:1)
我认为您应该使用trie structure来解决此任务。我将描述算法覆盖从索引0开始的所有子串 - 然后可以应用相同的算法从其他索引开始检查子串。
步骤:
注意:一旦处理到某个深度(比如3个符号),算法就可以停止。具有最高值的trie中的节点将是最常见的模式。你想要拿同样长度的最长的那个。
复杂度:
O(N M A ^ K)其中N - 行数,M - 每行中的字母数,A - 字母大小(例如遇到的不同字母数)K - 最大模式要检查的长度。
答案 2 :(得分:1)
你可以使用这个算法我逐行汇总,然后迭代模式并检查它们是否与其他线条模式匹配。
Pattern[] getPatternsForLine(String line){
ArrayList<Pattern> patterns=new ArrayList<Pattern>();
String temp=""; //what we will store the current pattern int
boolean inPattern=false;
for(char character:line.toCharArray()){
if(!"-".equals(character)){
temp=temp+character;
}else{
if(inPattern){
boolean existsInLine=false;//already exists?
for(Pattern p:patterns){
if(p.pattern.equals(temp)){
p.occurences++;
existsInLine=true;
break;
}
}
if(!existsInLine)
patterns.add(new Pattern(temp));
}
inPattern=false;
temp="";
}
}
return patterns.toArray();
}
class Pattern{
public String pattern;
public int occurences;
public Pattern(String pattern){
this.pattern=pattern;
occurences=1;
}
}