Сравнить строку с массивом строк и вывести наиболее полные совпадения - Visual Basic .NET
Формулировка задачи:
Доброго времени!
Задачку решил на своем уровне знания, но код получился ППЦ тяжелый, некрасивый, и жрущий память. Помогите переделать/оптимизировать.
Вводные данные: Есть строка, состоящая из нескольких слов (от 1 до 10).
Есть массив из подобных строк.
Есть слова-исключения.
Задача: Сравнить исходную строку с каждой из массива, выбрать те, в которой совпадает максимальное количество слов, не учитывая слова-исключения.
Мой код (постарался максимально откомментировать):
Листинг программы
- Imports System.Text.RegularExpressions
- Module String_select
- Public one_str As String = "Вася ел бутерброд с маслом" ' строка для поиска
- Public other_strings = {
- "Петя ел кашу с маслом",
- "Вася кашу с маслом тоже ел",
- "Петя бутерброд с икрой уронил",
- "Вася бутерброд с маслом уронил",
- "Петя ел бутерброд с маслом"} 'массив строк в которых искать совпадения
- Public iskl_word As String() = {"Вася", "Петя"} 'слова не участвующие в поиске, слова-исключения
- Public str1 As String = "не найдено"
- Sub Main()
- Dim k_mn As Integer 'коэффициент множественного совпадения (если результат не одна строка, а несколько)
- Dim k_t(0) As Integer ' массив номеров строк при множественном совпадении
- Dim ResultStr As String = "" 'вывод результата при множественном совпадении
- Dim k As Integer
- Dim s As Integer
- Dim s1 As Integer = 0
- Dim rg As Regex = New Regex("([А-Яа-я-]+)") 'любое слово
- Dim rg_m As MatchCollection = rg.Matches(one_str) 'Коллекция из СОВПАДЕНИЙ отдельных слов в исходной строке
- Dim n As Integer = rg_m.Count 'количество отдельных слов в one_str
- Dim rg_new(n) As Regex ' коллекция из ОТДЕЛЬНЫХ СЛОВ в исходной строке (для сравнения)
- Dim rg_fin As Match
- For index = 0 To other_strings.GetUpperBound(0) ' от 0 до количества строк в массиве, цикл по каждой отдельной строке из other_string
- For index1 = 0 To n - 1 ' от 0 до размера коллекции слов -1 , цикл по каждому отдельному слову в исходной строке
- str1 = rg_m.Item(index1).Value
- rg_new(index1) = New Regex(str1) ' заполняем коллекцию из отдельных слов
- If Array.FindIndex(iskl_word, AddressOf check_element) < 0 Then 'проверяем на слова-исключения
- rg_fin = rg_new(index1).Match(other_strings(index)) ' параллельно ищем совпадения по каждому слову из one_str в строке из other_string
- If rg_fin.Success = True Then 'если есть совпадение
- s = s + 1 'накручиваем счетчик совпадений
- End If
- End If
- Next
- If s > s1 Then ' если количество совпадений в данной строке больше максимального в предыдущих
- k_mn = 0 'обнуляем множественное совпадение
- s1 = s ' максимальное количество совпадений равно текущему
- k = index ' номер строки с максимальным совпадением
- k_t.SetValue(k, 0) ' делаем массив 1х1 (0 - индекс)
- ReDim Preserve k_t(0)
- ElseIf s = s1 Then ' если одинаковое количество совпадений
- k_mn = 1 ' задействуем коэффициент множественного совпадения
- ReDim Preserve k_t(k_t.Length) ' увеличиваем длину массива с номерами строк совпадений
- k_t.SetValue(index, k_t.GetUpperBound(0))
- End If
- s = 0
- Next
- If k_mn = 0 Then 'если одна строка имеет максимальное совпадение
- ResultStr = other_strings(k)
- Else 'если несколько строк имеют максимальное совпадение
- For j = 0 To k_t.GetUpperBound(0)
- ResultStr = ResultStr & other_strings(k_t(j)) & vbCrLf
- Next
- End If
- MsgBox(ResultStr)
- End Sub
- Private Function check_element(ByVal str As String) As Boolean
- Dim result As Boolean = False
- If str.Equals(str1) Then result = True
- Return result
- End Function
- End Module
Решение задачи: «Сравнить строку с массивом строк и вывести наиболее полные совпадения»
textual
Листинг программы
- Public one_str As String = "Вася ел бутерброд с маслом" ' строка для поиска
- Public other_strings() As String = {
- "Петя ел кашу с маслом",
- "Вася кашу с маслом тоже ел",
- "Петя бутерброд с икрой уронил",
- "Вася бутерброд с маслом уронил",
- "Петя ел бутерброд с маслом"} 'массив строк в которых искать совпадения
- Public iskl_word As String() = {"Вася", "Петя"} 'слова не участвующие в поиске, слова-исключения
- Public str1 As String = "не найдено"
- Private delim As Char = " "c
- Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
- Dim sPattern() As String = exWordDeletion(one_str, iskl_word).Split(delim)
- Dim nnS(other_strings.Length - 1) As Integer
- Dim sSource As String
- For i = 0 To other_strings.Length - 1
- sSource = exWordDeletion(other_strings(i), iskl_word)
- nnS(i) = sWordEqualCount(sSource, sPattern)
- Next
- MsgBox("Максимальное число совпадений = " & nnS.Max & vbCrLf & "в строке: " & other_strings(Array.IndexOf(nnS, nnS.Max)))
- End Sub
- Private Function exWordDeletion(ByVal sSrc As String, ByVal sEx As String()) As String
- Dim wSrc() As String = sSrc.Split(delim)
- Dim rz() As String = wSrc.Except(sEx).ToArray
- Return String.Join(delim, rz)
- End Function
- Private Function sWordEqualCount(ByVal sSrc As String, ByVal sPtn As String()) As Integer
- Dim wSrc() As String = sSrc.Split(delim)
- Dim rz() As String = wSrc.Intersect(sPtn).ToArray
- Return rz.Count
- End Function
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д