我想在VB.Net中的字符串中找到重复序列,如:
Dim test as String =“EDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGB”
我希望程序检测重复序列,以防EDCRFVTGB并计算重复次数。我的问题是找到字符串中的重复序列,我搜索了几种方法来做,但我没有得到解决方案,我尝试了快速排序算法,重复算法,但其中一些不能用于字符串。
我虽然创建了子串并检查它们是否存在于字符串中,但我不知道如何获取子字符串,因为字符串上没有模式,字符串中也可能没有重复序列
答案 0 :(得分:1)
首先检查目标字符串的一半是否重复两次。如果没有,检查字符串的三分之一是否重复三次。如果没有,检查字符串的四分之一是否重复四次。这样做直到找到匹配的序列。跳过商数不是整数的任何除数,使其表现更好。此代码应该可以解决这个问题并填写此描述无法澄清的任何空白:
Public Function DetermineSequence(ByVal strTarget As String) As String
Dim strSequence As String = String.Empty
Dim intLengthOfTarget As Integer = strTarget.Length
'Check for a valid Target string.
If intLengthOfTarget > 2 Then
'Try 1/2 of Target, 1/3 of Target, 1/4 of Target, etc until sequence is found.
Dim intCursor As Integer = 2
Do Until strSequence.Length > 0 OrElse intCursor = intLengthOfTarget
'Don't even test the string if its length is not a divisor (to an Integer) of the length of the target String.
If IsDividendDivisibleByDivisor(strTarget.Length, intCursor) Then
'Get the possible sequence.
Dim strPossibleSequence As String = strTarget.Substring(0, (intLengthOfTarget / intCursor))
'See if this possible sequence actually is the repeated String.
If IsPossibleSequenceRepeatedThroughoutTarget(strPossibleSequence, strTarget) Then
'The repeated sequence has been found.
strSequence = strPossibleSequence
End If
End If
intCursor += 1
Loop
End If
Return strSequence
End Function
Private Function IsDividendDivisibleByDivisor(ByVal intDividend As Integer, ByVal intDivisor As Integer) As Boolean
Dim bolDividendIsDivisbleByDivisor As Boolean = False
Dim intOutput As Integer
If Integer.TryParse((intDividend / intDivisor), intOutput) Then
bolDividendIsDivisbleByDivisor = True
End If
Return bolDividendIsDivisbleByDivisor
End Function
Private Function IsPossibleSequenceRepeatedThroughoutTarget(ByVal strPossibleSequence As String, ByVal strTarget As String) As Boolean
Dim bolPossibleSequenceIsRepeatedThroughoutTarget As Boolean = False
Dim intLengthOfTarget As Integer = strTarget.Length
Dim intLengthOfPossibleSequence As Integer = strPossibleSequence.Length
Dim bolIndicatorThatPossibleSequenceIsCertainlyNotRepeated As Boolean = False
Dim intCursor As Integer = 1
Do Until (intCursor * intLengthOfPossibleSequence) = strTarget.Length OrElse bolIndicatorThatPossibleSequenceIsCertainlyNotRepeated
If strTarget.Substring((intCursor * intLengthOfPossibleSequence), intLengthOfPossibleSequence) <> strPossibleSequence Then
bolIndicatorThatPossibleSequenceIsCertainlyNotRepeated = True
End If
intCursor += 1
Loop
If Not bolIndicatorThatPossibleSequenceIsCertainlyNotRepeated Then
bolPossibleSequenceIsRepeatedThroughoutTarget = True
End If
Return bolPossibleSequenceIsRepeatedThroughoutTarget
End Function
答案 1 :(得分:1)
这是一个示例,它允许您指定序列的最小和最大长度,并返回一个名为sequence的自定义类的列表,其中有多个匹配项。序列类将包含找到的模式和模式发生的索引列表。
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.Items.Clear()
ListView1.Columns.Clear()
ListView1.Columns.Add("Sequence")
ListView1.Columns.Add("Indexes of occurrence")
Dim sequences As List(Of Sequence) = DetectSequences("EDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGB")
For Each s As Sequence In sequences
Dim item As New ListViewItem(s.Sequence)
item.Tag = s
item.SubItems.Add(s.IndexesToString)
ListView1.Items.Add(item)
Next
ListView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize)
End Sub
Function DetectSequences(s As String, Optional minLength As Integer = 5, Optional MaxLength As Integer = 8) As List(Of Sequence)
Dim foundPatterns As New List(Of String)
Dim foundSequences As New List(Of Sequence)
Dim potentialPattern As String = String.Empty, potentialMatch As String = String.Empty
For start As Integer = 0 To s.Length - 1
For length As Integer = 1 To s.Length - start
potentialPattern = s.Substring(start, length)
If potentialPattern.Length < minLength Then Continue For
If potentialPattern.Length > MaxLength Then Continue For
If foundPatterns.IndexOf(potentialPattern) = -1 Then
foundPatterns.Add(potentialPattern)
End If
Next
Next
For Each pattern As String In foundPatterns
Dim sequence As New Sequence With {.Sequence = pattern}
For start As Integer = 0 To s.Length - pattern.Length
Dim length As Integer = pattern.Length
potentialMatch = s.Substring(start, length)
If potentialMatch = pattern Then
sequence.Indexes.Add(start)
End If
Next
If sequence.Indexes.Count > 1 Then foundSequences.Add(sequence)
Next
Return foundSequences
End Function
Public Class Sequence
Public Sequence As String = ""
Public Indexes As New List(Of Integer)
Public Function IndexesToString() As String
Dim sb As New System.Text.StringBuilder
For i As Integer = 0 To Indexes.Count - 1
If i = Indexes.Count - 1 Then
sb.Append(Indexes(i).ToString)
Else
sb.Append(Indexes(i).ToString & ", ")
End If
Next
Return sb.ToString
End Function
End Class
Private Sub ListView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListView1.SelectedIndexChanged
If ListView1.SelectedItems.Count = 0 Then Exit Sub
RichTextBox1.Clear()
RichTextBox1.Text = "EDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGBEDCRFVTGB"
Dim selectedSequence As Sequence = DirectCast(ListView1.SelectedItems(0).Tag, Sequence)
For Each i As Integer In selectedSequence.Indexes
RichTextBox1.SelectionStart = i
RichTextBox1.SelectionLength = selectedSequence.Sequence.Length
RichTextBox1.SelectionBackColor = Color.Red
Next
End Sub
End Class
答案 2 :(得分:0)
你知道字符串的起源吗? 你知道它有多久了吗?
直截了当的算法是:
for each character index i
for each character index after that j
compare substring(i, j-i) to substring(j, j-i)
if equal, record as a found repeating substring
有一些优化,比如知道字符串不能超出字符串的末尾(j的上限),只查找比你刚才找到的字符串更长的子字符串。
这不是超级有效的(N平方),但是一个相关的广义问题(“编辑距离”)也不比N平方好,所以你去。
答案 3 :(得分:-1)
这是一种算法,它以这样的方式生成所有重复序列,使得它们按长度和第一次出现排序。它基于一个简单的想法:在一个句子中找到一个单词两次,相同的起始字母必须出现两次。
带有一些解释的Java代码(算法保持不变),它将输出交织的重复,例如BANANA =&gt; A,N,AN,NA,ANA(1,3),你可以消除一个索引,如果前一个的距离小于字符串长度,在这个算法中纠正它(在代码下面是一个样本运行,应该更好地解释一下):
public List<String> getRepetitions(String string) {
List<String> repetitions = new ArrayList<String>();
Map<String, List<Integer>> rep = new HashMap<String, List<Integer>>(), repOld;
// init rep, add start position of all single character length strings
for (int i = 0; i < string.length(); i++) {
String s = string.substring(i, i + 1); // startIndex inclusive, endIndex exclusive
if (rep.containsKey(s)) {
rep.get(s).add(new Integer(i));
} else {
List<Integer> l = new ArrayList<Integer>();
l.add(new Integer(i));
rep.put(l);
}
}
// eliminate those with no repetitions and add the others to the solution
for (Map.Entry<String, Integer> e : rep.entrySet()) {
if (e.getValue().size() < 2) {
rep.remove(e.getKey());
} else {
repetitions.add(e.getKey());
}
}
for (int len = 1; rep.size() > 0; len++) {
repOld = rep;
rep = new HashMap<String, List<Integer>>();
for (Map.EntrySet<String, List<Integer>> e : repOld.entrySet()) {
for (Integer i : e.getValue()) { // for all start indices
if (i.intValue() + len + 1 >= string.length())
break;
String s = e.getKey() + string.charAt(i.intValue() + len + 1);
if (rep.containsKey(s)) {
rep.get(s).add(i);
} else {
List<Integer> l = new ArrayList<Integer>();
l.add(i);
rep.put(l);
}
}
}
// eliminate repetitions and add to solution
for (Map.Entry<String, Integer> e : rep.entrySet()) {
if (e.getValue().size() < 2) {
rep.remove(e.getKey());
} else {
repetitions.add(e.getKey());
}
}
}
return repetitions; // ordered by length, so last = longest
}
BANANA的样本运行:
rep
=&gt; B - &gt; [0],A - &gt; [1,3,5],N - > [2,4] rep
):AN - &gt; [1,3],NA - > [2,4] rep
中的