Палиндромы и VB

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Экселенц
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 4
Зарегистрирован: 30.01.2006 (Пн) 15:25

Палиндромы и VB

Сообщение Экселенц » 30.01.2006 (Пн) 17:21

Здравствуйте форумчане!

Если кто-то из вас по доброй воле может мне помочь, то мой вопрос о алгоритме на VB:
есть палиндром(строка, к-я читается одинаково справа и слева, например АВВА) изл латинских букв А и В. Число N - это кол-во букв в палиндроме, 1=< N =<100. Есть запрещенная строка (S) , длинной не более 5 символов, например "ВАВ". Надо подсчитать, сколько есть палиндомов, длинной N не содержащих запрещенную строку S.
Мой первый алгоритм перебирал все допустимые комбинации А и В и выбирал из них допустимые палиндромы. Но это очень долго и комп повесился :clown: - возьмите двоичное число из ста единичек, перевидите его в двоичное, и получите биллиарды комбинаций, которые можно перебирать часами.
Сдесь я представлю модифицированный алгоритм, который делает работу в 2 раза быстрее, но и этого недостаточно - комп тормозит уже при 30 символов в строке. Алгоритм перебирает комбинации А и В в подстроке HalfStr, длинна к-й в 2 раза меньше N, потом к строке Stroka добавляется HalfStr и StrReverce(HalfStr) - перевернутый HalfStr. Таким образом генерируются заведомо палиндромные строки.

Stroka =HalfStr & StrReverce(HalfStr).

Если N - нечетное, то между HalfStr и StrReverce(HalfStr) ставится сначало А потом В.

Stroka =HalfStr & "A" & StrReverce(HalfStr)
Stroka =HalfStr & "B" & StrReverce(HalfStr)

Уже потом, если Stroka не содержит S то счетчик повышается на 1.
Но и этот алгоритм тормозит. Если у кого-нибудь есть идеи на счет того, как этот алгоритм выполнить быстрее, и если Вы захотите поделится своими идеями, то я буду очень благодарен :))
Вложения
polyndrom.zip
Алгоритм
(1.6 Кб) Скачиваний: 24
Стояли звери около двери.
в них стреляли, они умирали..

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 30.01.2006 (Пн) 17:30

Что-то не очень понял.
Текст палиндрома может быть произвольным или осмысленным?
Если произвольным и нужно знать только количество вариантов (а не сами варианты), то я бы делал наоборот -- посчитал бы количество всех вариантов и отнял бы количество вариантов с запрещенной строкой.
Lasciate ogni speranza, voi ch'entrate.

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 30.01.2006 (Пн) 17:50

Кажется число палиндромов из n буков это
2^int(n/2)*(1+(n/2-int(n/2))*2)
--
Add:
Проще так 2^int(n/2)*(1 + n mod 2)
--
Но надо проверить...

возьмите двоичное число из ста единичек, перевидите его в двоичное

Эээ... :? :?: :?: :?:

ЗЫ Кстати 2*30 это всего 10^9 а 2^16 и того меньше... Комп не должен вешаться даже на рассчете всех палиндромов и их запоминании. Точнее должен, но не так уж сильно )) По крайне мере, 30-40 символов ИМХО должен спокойно просчитывать меньше чем за минуту (хотя я не проверял конечно)
Последний раз редактировалось GAGArin 30.01.2006 (Пн) 18:34, всего редактировалось 1 раз.

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 30.01.2006 (Пн) 18:23

Поторопился я однако, думал запрещенная строка может только в центре быть. (ты просто в качестве примера привел тоже палиндром) Выводить формулу для "запрещенных" не буду, скажу только что она зависит от того палиндром S или нет. А думать что-то лениво...
Последний раз редактировалось GAGArin 30.01.2006 (Пн) 18:35, всего редактировалось 1 раз.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 30.01.2006 (Пн) 18:27

Хм...

У меня получилось тождественная, но другая формула - 2 ^ (Int(N / 2) + (N Mod 2)) :)

Что же касается этого перебора, то... то сегодня я пойду спать :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

vvs_adm
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1492
Зарегистрирован: 03.02.2005 (Чт) 3:45
Откуда: оттуда ;)

Сообщение vvs_adm » 30.01.2006 (Пн) 18:47

GAGArin писал(а):Кажется число палиндромов из n буков это
2^int(n/2)*(1+(n/2-int(n/2))*2)
--
Add:
Проще так 2^int(n/2)*(1 + n mod 2)
--
Но надо проверить...
а по моему число палиндромов из n символов равно:
2 ^ ((n+1)\2)
Никогда не откладывай на завтра то, что можно ... отложить на послезавтра!

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 30.01.2006 (Пн) 19:11

vvs_adm
Ню, ню ) Каждому свое конечно :wink: А вообще просто я не помнил как округляет "\" а смотреть лениво было.

Экселенц
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 4
Зарегистрирован: 30.01.2006 (Пн) 15:25

Сообщение Экселенц » 31.01.2006 (Вт) 6:44

alibek писал(а):Что-то не очень понял.
Текст палиндрома может быть произвольным или осмысленным?
Если произвольным и нужно знать только количество вариантов (а не сами варианты), то я бы делал наоборот -- посчитал бы количество всех вариантов и отнял бы количество вариантов с запрещенной строкой.


Палиндром неосмысленный, просто набор из N символов, а сделать так, как вы хотите я думал, но проблема в расчете количества вариантов С запрещенной строкой. (общее количествово - то палиндромов можно подсчитать)
Стояли звери около двери.
в них стреляли, они умирали..

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 31.01.2006 (Вт) 9:13

Экселенц писал(а):но проблема в расчете количества вариантов С запрещенной строкой. (общее количествово - то палиндромов можно подсчитать)

И в чем же эта проблема?
Допустим, S=3 (три символа в запрещенной строке), а N=7 (семь символов в палиндроме). Если "палиндромные" символы отмечать, как +, а запрещенные, как *, то получаться следующие варианты:
***++++
+***+++
++***++
+++***+
++++***
Т.е. число вариантов равно числу вариантов, умноженному на (N-S-1).
Lasciate ogni speranza, voi ch'entrate.

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 31.01.2006 (Вт) 10:18

Одну формулу тут не вывести, но все же писать полный перебор тоже не стоит.

Строим массив строк с запрещенной строкой (как сказал alibek) Проверяем его на дополнимость до палиндромов и по возможности или дополняем или выкидываем строку.
"++АА.Б+++" - выбрасываем т.к. он недополним
"+++А.АБ++" - дополняем до "++БА.АБ++"
Пробегаемся по массиву и ищем одинаковые варианты, если находим, оставляем один из двух (больше двух одинаковых вроде получиться не должно)

Теперь просто пускаем нашу формулу от числа плюсиков в каждой строке и складываем. Получаем все запрещенные палиндромы.

ЗЫ Кстати формулу числа палиндромов надо дополнить вариантом
F(0)=0

Экселенц
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 4
Зарегистрирован: 30.01.2006 (Пн) 15:25

Сообщение Экселенц » 31.01.2006 (Вт) 14:00

alibek писал(а):
Экселенц писал(а):но проблема в расчете количества вариантов С запрещенной строкой. (общее количествово - то палиндромов можно подсчитать)

И в чем же эта проблема?
Допустим, S=3 (три символа в запрещенной строке), а N=7 (семь символов в палиндроме). Если "палиндромные" символы отмечать, как +, а запрещенные, как *, то получаться следующие варианты:
***++++
+***+++
++***++
+++***+
++++***
Т.е. число вариантов равно числу вариантов, умноженному на (N-S-1).


Но может быть и
***+***
+***+++
++***++
+++***+
***+***

а если N=10, то
***++++***
***+***+++
*** ***+***
+++***+***
***+*** +++
т.е. запрещенная сторка будет встечатся более 1 раза, => запрещенных палиндромов будет гораздо больше.

Простите, в предыдущем посте я не уточнил, что это неосмысленный набор из N символов "A" и "B", латинских.
Стояли звери около двери.
в них стреляли, они умирали..

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 31.01.2006 (Вт) 14:12

Экселенц писал(а):Но может быть и

В этом нет смысла.
Если будут исключены ***++++, то в это множество будет также входить и ***+***.
Lasciate ogni speranza, voi ch'entrate.

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 31.01.2006 (Вт) 14:36

Экселенц
Тогда только полный перебор. Сейчас посижу, посмотрю что там можно сделать для оптимизации...

alibek
Если найдешь другое решение, потесть его и поймешь что оно не подходит. Для начала скажи сколько запрещенных палиндромов для N=7 и S="ABB" Просто по формулам.

Экселенц
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 4
Зарегистрирован: 30.01.2006 (Пн) 15:25

Сообщение Экселенц » 31.01.2006 (Вт) 14:50

GAGArin писал(а):
Эээ... :? :?: :?: :?:

ЗЫ Кстати 2*30 это всего 10^9 а 2^16 и того меньше... Комп не должен вешаться даже на рассчете всех палиндромов и их запоминании. Точнее должен, но не так уж сильно )) По крайне мере, 30-40 символов ИМХО должен спокойно просчитывать меньше чем за минуту (хотя я не проверял конечно)


1111111111111111111111111111111111111111111111111111111111111111
(66 единичек)в двоичной равно
18446744073709551615
в десятичной.
Стояли звери около двери.
в них стреляли, они умирали..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 31.01.2006 (Вт) 15:02

Максимум 100.
Поскольку это палиндром, он определяется своей первой половиной, то есть реальный максимум - 50.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 31.01.2006 (Вт) 16:51

Вобщем где-то 50 символов перебирает за 30-40 секунд, больше еще не ставил. Просто полный перебор с отсечениями причем не в лучшем исполнении (т.к. в моем, а я в VB не силен)

Можно чисто теоретически сделать это передавая не строку, а байт, но мне не хотелось колупаться.

Код: Выделить всё
Public intN As Integer
Public intK As Integer
Public IntHalf As Integer
Public strS As String
Public lngCount As Long
Public boolChet As Boolean

Private Function strZerro(intCount As Integer) As String
For intT = 1 To intCount
  strZerro = strZerro + "*"
Next intT
End Function

Private Function strMirror(strWord As String) As String
strLeft = strWord + strZerro(IntHalf - Len(strWord))
strMirror = strLeft
If boolChet Then
  For intT = 1 To IntHalf
    strMirror = strMirror + Mid(strLeft, IntHalf - intT + 1, 1)
  Next intT
Else
  For intT = 1 To IntHalf - 1
    strMirror = strMirror + Mid(strLeft, IntHalf - intT, 1)
  Next intT
End If
End Function

Private Function boolPoisk(strWord As String) As Boolean
strnow = strMirror(strWord)
For intT = 1 To intN - intK + 1
  If Mid(strnow, intT, intK) = strS Then
    boolPoisk = True
    Exit Function
  End If
Next intT
End Function

Private Sub Pali(strWord As String)
If Not boolPoisk(strWord) Then
  If Len(strWord) = IntHalf Then
    lngCount = lngCount + 1
  Else
    Pali (strWord + "A")
    Pali (strWord + "B")
  End If 
End If
End Sub


Private Sub Command1_Click()
strS = "ABB"
intN = 50
IntHalf = (intN + 1) \ 2
intK = Len(strS)
If intN / 2 = intN \ 2 Then boolChet = True

Pali ("")
MsgBox (lngCount)
End Sub


PS А так хотелось решить задачу математически :cry:

Ах да, комментов не будет (по крайней мере сегодня) strS - запретная строка, intN - нужная длинна. Остальное потом.

GAGArin
Неистовый флудер
Неистовый флудер
 
Сообщения: 1777
Зарегистрирован: 23.12.2002 (Пн) 12:46
Откуда: я тут взялся, не знаю...

Сообщение GAGArin » 31.01.2006 (Вт) 20:02

За 2 часа, сотню прога не вытянула, ушла в астрал. Но сотню я и не обещал )


Вернуться в Visual Basic 1–6

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

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

    TopList