2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 18:02 
Привет всем. Небольшая и лёгкая тема уже, наверно, решена. Уделите пожалуйста мне немного времени :roll:

Написал я такую процедуру поиска симметричной строки в массиве:
Код:
 
    Sub Bolsim(ByVal f() As String, ByVal n As Integer, ByRef zs As Integer)
        Dim i As Integer
        Dim j As Integer
        Dim m As Integer
        Dim a As Integer
        Dim l As Integer
        Dim dn As String
        Dim dk As String

        For i = 0 To n - 1
            a = 0
            m = CShort(f(i).Length) 'длина строки
            l = m
            For j = 1 To m
                dn = Mid$(f(i), j, 1)
                dk = Mid$(f(i), l, 1)
                l = l - 1
                If dn = dk Then
                    a = a + 1
                    If a = m Then
                        zs = i
                    End If
                Else
                    Exit For
                End If
            Next
        Next
    End Sub

zs - это индекс симметричного элемента.
Одна только проблема, действий в процедуре в 2 раза больше чем нужно For j = 1 To m. Но если сделать For j = 1 To CInt(m / 2), то данная процедура не будет учитывать симметричные строки с нечётным кол-вом элементов.

Какой способ применить?
Такой?:
Код:
    Sub Bolsim(ByVal f() As String, ByVal n As Integer, ByRef zs As Integer)
        Dim i As Integer
        Dim j As Integer
        Dim m As Integer
        Dim a As Integer
        Dim l As Integer
        Dim dn As String
        Dim dk As String
        Dim vov As Integer
        For i = 0 To n - 1
            a = 0
            m = CShort(f(i).Length) 'длина строки
            vov = 0
            If (m / 2 <> m \ 2) Then
                vov = 1
            End If
            l = m
            For j = 1 To CInt((m - vov) / 2)
                dn = Mid$(f(i), j, 1)
                dk = Mid$(f(i), l, 1)
                l = l - 1
                If dn = dk Then
                    a = a + 1
                    If a = ((m - vov) / 2) Then
                        zs = i
                    End If
                Else
                    Exit For
                End If
            Next
        Next
    End Sub


Просьба не задаваться вопросом - "а если в массиве нет симметричных строк или их несколько?" Это вопрос я решу чуть позже.

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 18:30 
Я б так сделал:
Код:
m <- длина строки
l <- (m+1) / 2
For j = 1 to l
    If Mid(f(i),j,1) <> Mid(f(i), m+1-j, 1) Then
        строка несимметричная
    End If
Next
В случае строки нечетной длины выполняется одно лишнее сравнение центрального символа самого с собой.

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 18:33 
Аватара пользователя
А почему не до эм делить на два? Зачем сравнивать с собой? Сэкономим одно сравнение.
и одно прибавление единицы :-)
И исчо можно из цикла выпрыгивать на ходу, хотя это плохие манеры. Ну сравнение запихать в условие антил какое-нить.
Ловим блошек-с

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 18:41 
gris в сообщении #303658 писал(а):
А почему не до эм делить на два?
Сложно сказать. Вразумительного оправдания придумать не удалось. :mrgreen:

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 19:00 
Спасибо все) Обдумаю)

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 02:31 
Я тут до такого дошёл :shock:
Если есть задание:
Цитата:
Найти самую длинную симметричную строку, читающуюся одинаково слева направо и справа налево, в заданном массиве строк.


То надо ли учитывать, что строка может состоять из одного символа??? :shock:
Это уже такой философский вопрос))
С одной стороны, 1 символ это тоже строка, которая обладает чисто символической "симметрией", т.к. её нельзя разделить и проверить симметричность. С другой стороны, в задании написано "читающуюся одинаково слева направо и справа налево". Т.е. получается если строка состоит из одного символа, то мы же не можем её прочитать справа или слева... и тогда получается, что строку из 1-го символа учитывать(в задании) не надо.

Ещё в инете нашёл такую штуку - "Палиндром". В определении это набор чего-то читающегося одинаково слева направо и справа налево. И кое-где написано, что он может состоять из одной буквы. Может и здесь тогда одна буква это тоже - симметричная строка, читающаяся одинаково слева направо и справа налево?
Ещё кое-где написано:
Цитата:
По свойству палиндрома можно понять, что каждая буква должна иметь пару (т.е. входить в палиндром четное количество раз), кроме, возможно, одной буквы, которая будет находиться ровно посередине палиндрома (она будет парной “сама с собой”).

А это уже совсем наоборот.


Ппц. Голов кругом идёт. :shock:

Помогитеее пожалуйста :-(

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 09:19 
Аватара пользователя
Вы коснулись очень интересной темы. Предположим, Вы написали программульку, которая с Вашей точки зрения полностью и в точности соответствует пожеланиям заказчика. Отнюдь не стоит ожидать такого же мнения о продукте со стороны заказчика. Желая преуменьшить гонорар, он будет всячески уверять Вас, что имел в виду, что симметричные строки никогда из одного символа не состояли, и вот теперь из-за Вас у него срывается кредит Омереканского банка. А сумма гонорара в рублях, молодой человек, что Вы, какие доллары.

Так что всё надо заранее прописывать в техническом задании сиречь в условии. Что такое симметричная строка. Надо ли выводить последнюю, первую или все вместе. Каков максимальные размер строки и максимальный размер массива. Иначе на просторах инета можно отыскать два противоположных определения.

Кстати, как только Вы найдёте очередную симметричную строку, строки меньшей длины можно вообще не проверять на симметричность. Это я о том, что насколько бы хорошую программу не написали, всегда найдётся остроглазый умник, который её улучшит :-) То есть препод скажет - а вот этот оператор можно было вынести за цикл. Что же Вы не заметили? Ну так и быть, четвёрку поставлю.

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 09:42 
Maslov в сообщении #303655 писал(а):
Я б так сделал:
Код:
m <- длина строки
l <- (m+1) / 2
For j = 1 to l
    If Mid(f(i),j,1) <> Mid(f(i), m+1-j, 1) Then
        строка несимметричная
    End If
Next

Тогда уж так:

Код:
m <- длина строки
k <- (m+1) / 2
строка симметричная
For j = 1 to k
    If Mid(f(i),j,1) <> Mid(f(i), m+1-j, 1) Then
        строка несимметричная
    End If
Next

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 09:59 
Было у меня такое задание:
Цитата:
Найти самую длинную симметричную строку, читающуюся одинаково слева направо и справа налево, в заданном массиве строк.


Вот самая главная процедура, которая ищет наиб. сим. строку:
(n - это кол-во строк массива, которое пользователь сам указывает в начале работы программы)

Код:
    'процедура поиска самой длинной симметричной строки
    Sub Bolsim(ByVal f() As String, ByVal n As Integer, ByRef zs As String)
        Dim i As Integer
        Dim j As Integer
        Dim k As Integer
        Dim m As Integer
        Dim a As Integer
        Dim l As Integer
        Dim vov As Integer
        Dim max As Integer
        Dim bl As Integer
        Dim d(n) As Integer
        Dim u As Integer
        Dim pl As Integer
        zs = "не найдена"
        max = 0
        bl = 0
        u = 0
        pl = 0
        For i = 0 To n - 1
            a = 0
            m = CShort(f(i).Length) 'длина строки
            vov = 0
            If (m / 2 <> m \ 2) Then
                vov = 1
            End If
            l = m
            For j = 1 To CInt((m - vov) / 2)
                If Mid$(f(i), j, 1) = Mid$(f(i), l, 1) Then
                    l = l - 1
                    a = a + 1
                    If a = ((m - vov) / 2) And m >= max Then
                        zs = f(i)
                        d(u) = i 'массив индексов сим.элементов
                        u = u + 1
                        max = m
                    End If
                Else
                    Exit For
                End If
            Next
        Next

        If u > 0 Then
            'код ниже помогает избежать ошибки, когда в массиве строк
            'имеется несколько "наидлинных" строк
            For k = 0 To u - 1
                If CShort(f(d(k)).Length) = max Then
                    pl = pl + 1
                End If
            Next
            If pl > 1 Then
                zs = "не найдена"
            End If
        End If

    End Sub


Протестировал, вроде работает отлично. Боюсь только училка придерётся и скажет "Так не делается" или "Это по-деревенски". А я как будто точно должен знать как надо делать :?

(Оффтоп)

Я, кстати, ненавижу когда училка говорит "это по деревенски". Типо городские такие умные, а деревенские - глупые. Я сам всю жизнь в городе живу, но к жителям деревень хорошо отношусь. И они вовсе не глупые. Если у них нет возможность получить образование - это не показатель их тупости! :?


Помогите please :-(

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 19:05 
Mikle1990 в сообщении #303878 писал(а):
Я, кстати, ненавижу когда училка говорит "это по деревенски". Типо городские такие умные, а деревенские - глупые. Я сам всю жизнь в городе живу, но к жителям деревень хорошо отношусь. И они вовсе не глупые. Если у них нет возможность получить образование - это не показатель их тупости!

Вы правильно заметили. В Дураковках и Самодуровках не дураки живут, так как деревенские учатся по тем же программам, что и гггггородские. Сам я вообще хуторской парень.
Mikle1990. Я бы Вам помог, если бы в совершенстве владел компьютером. gris наверняка поможет.

 
 
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение30.03.2010, 22:14 
2Mikle1990
Цитата:
Ещё в инете нашёл такую штуку - "Палиндром"

Ну да, это оно и есть.

Цитата:
И кое-где написано, что он может состоять из одной буквы.

И правильно написано. Это тривиальный случай.

Цитата:
Цитата:
По свойству палиндрома можно понять, что каждая буква должна иметь пару (т.е. входить в палиндром четное количество раз), кроме, возможно, одной буквы, которая будет находиться ровно посередине палиндрома (она будет парной “сама с собой”).


А это уже совсем наоборот.

Не вижу противоречия, перечитайте вашу цитату ещё раз.

Цитата:
Помогите please

Честно говоря, я уже успел подзабыть VB и разобраться с вашим кодом мне пока не удалось. Покажу как я бы решал поставленную задачу.

Во-первых, я бы написал функцию Scan, возвращающую искомый результат или пустую строку в случае отсутствия симметричных строк:
Используется синтаксис Visual Basic
Function Scan(Strings As Collection) As String
    Scan = ""

    For Each Item In Strings
        If Palindrome(Item) Then _
            If Len(Item) > Len(Scan) Then _
                Scan = Item
    Next Item
End Function
 


Во-вторых, я бы написал предикат Palindrome, проверяющий симметричность строки:
код: [ скачать ] [ спрятать ]
Используется синтаксис Visual Basic
Function Palindrome(Line) As Boolean
    L = 1
    R = Len(Line)
   
    Palindrome = False
   
    Do While L < R
        If (Mid(Line, L, 1) <> _
            Mid(Line, R, 1)) Then _
                Exit Function
   
        L = L + 1
        R = R - 1
    Loop
   
    Palindrome = True
End Function
 


Ну и наконец попытался бы потестить программульку:
Используется синтаксис Visual Basic
    Dim Strings As New Collection

    With Strings
        .Add "abcba"
        .Add "123454321"
        .Add "fdghgdf"
        .Add "sdfdfsdf"
    End With
   
    Result = Scan(Strings)
    If Result <> "" Then MsgBox Result
 


Получилось, как видите, довольно компактно. Правда, ищется лишь одна из наибольших по длине симметричных строк и не производится предварительное "сжатие" строки путем удаления из неё пробелов. Но это все легко исправляется.

 
 
 [ Сообщений: 11 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group