2014 dxdy logo

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

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




Начать новую тему Ответить на тему
 
 Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 18:02 


14/12/09
306
Привет всем. Небольшая и лёгкая тема уже, наверно, решена. Уделите пожалуйста мне немного времени :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 
Заслуженный участник


09/08/09
3438
С.Петербург
Я б так сделал:
Код:
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 
Заслуженный участник
Аватара пользователя


13/08/08
14496
А почему не до эм делить на два? Зачем сравнивать с собой? Сэкономим одно сравнение.
и одно прибавление единицы :-)
И исчо можно из цикла выпрыгивать на ходу, хотя это плохие манеры. Ну сравнение запихать в условие антил какое-нить.
Ловим блошек-с

 Профиль  
                  
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 18:41 
Заслуженный участник


09/08/09
3438
С.Петербург
gris в сообщении #303658 писал(а):
А почему не до эм делить на два?
Сложно сказать. Вразумительного оправдания придумать не удалось. :mrgreen:

 Профиль  
                  
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение28.03.2010, 19:00 


14/12/09
306
Спасибо все) Обдумаю)

 Профиль  
                  
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 02:31 


14/12/09
306
Я тут до такого дошёл :shock:
Если есть задание:
Цитата:
Найти самую длинную симметричную строку, читающуюся одинаково слева направо и справа налево, в заданном массиве строк.


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

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

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


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

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

 Профиль  
                  
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 09:19 
Заслуженный участник
Аватара пользователя


13/08/08
14496
Вы коснулись очень интересной темы. Предположим, Вы написали программульку, которая с Вашей точки зрения полностью и в точности соответствует пожеланиям заказчика. Отнюдь не стоит ожидать такого же мнения о продукте со стороны заказчика. Желая преуменьшить гонорар, он будет всячески уверять Вас, что имел в виду, что симметричные строки никогда из одного символа не состояли, и вот теперь из-за Вас у него срывается кредит Омереканского банка. А сумма гонорара в рублях, молодой человек, что Вы, какие доллары.

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

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

 Профиль  
                  
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение29.03.2010, 09:42 
Заслуженный участник


11/05/08
32166
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 


14/12/09
306
Было у меня такое задание:
Цитата:
Найти самую длинную симметричную строку, читающуюся одинаково слева направо и справа налево, в заданном массиве строк.


Вот самая главная процедура, которая ищет наиб. сим. строку:
(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 
Заблокирован


14/02/09

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

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

 Профиль  
                  
 
 Re: Поиск симметричной строки в массиве (VB)
Сообщение30.03.2010, 22:14 
Заслуженный участник


26/07/09
1559
Алматы
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 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group