Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 31.12.2008, 16:03   #1
cent
Пользователь
 
Аватар для cent
 
Регистрация: 26.12.2008
Сообщений: 73
Лампочка Генератор перестановок

Необходимо создать модуль, который будет генерировать все возможные перестановки элементов некоторого множества.
Поиск привел на такие источники:
Генерация перестановок в антилексикографическом порядке (на Си и на Прологе)
Генераторы перестановок
Размещение (Wiki)
но в них либо теория, либо готовые решения на языках программирования, отличных от VBA

Может кто-то сможет интерпретировать коды в VBA?
Или хотя бы подскажите алгоритм, код сам напишу.


Например: есть множество из 4х чисел: 1,2,3,4.
Необходимо сгенерировать все возможные их размещения, при этом каждое число должно присутствовать в варианте 1 раз.
Вот такой результат должен получиться:
Код:
1	2	3	4
1	2	4	3
1	3	2	4
1	3	4	2
1	4	2	3
1	4	3	2
2	1	3	4
2	1	4	3
2	3	1	4
2	3	4	1
2	4	1	3
2	4	3	1
3	1	2	4
3	1	4	2
3	2	1	4
3	2	4	1
3	4	1	2
3	4	2	1
4	1	2	3
4	1	3	2
4	2	1	3
4	2	3	1
4	3	1	2
4	3	2	1
Эта последовательность была сделана вручную Исходя из того, что существует несколько методов расстановки, результат может отличаться только в последовательности комбинаций.
Четко сформулированная задача - половина решения!
<= Спасибо оставляем в отзывах

Последний раз редактировалось cent; 31.12.2008 в 16:21.
cent вне форума
Старый 02.01.2009, 10:40   #2
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Попробуйте такой вариант:

Код:
Dim coll As Collection

Sub Sm(AlreadyS As String, S As String)
    If Len(S) = 1 Then coll.Add AlreadyS & S: Exit Sub
    For i = 1 To Len(S): Sm AlreadyS + Mid$(S, i, 1), Left$(S, i - 1) & Mid$(S, i + 1): Next
End Sub

Sub ЗаполнитьЯчейкиПерестановками(ByVal ТекстоваяСтрока As String, ByRef ПерваяЯчейка As Range)
    Dim ra As Range, ДлинаСтроки As Long
    ДлинаСтроки = Len(ТекстоваяСтрока): If ДлинаСтроки < 1 Or ДлинаСтроки > 9 Then MsgBox "error": Exit Sub

    Set coll = New Collection: Sm "", ТекстоваяСтрока

    Set ra = ПерваяЯчейка.Cells(1).Resize(coll.Count, ДлинаСтроки)
    Dim arr(): ReDim arr(1 To coll.Count, 1 To ДлинаСтроки): c = 1

    For Each Item In coll
        For i = 1 To ДлинаСтроки: arr(c, i) = Mid$(Item, i, 1): Next: c = c + 1
    Next
    ra.Value = arr    ' переносим массив на лист
    ra.EntireColumn.AutoFit
End Sub

Sub ЗаполнитьЯчейкиСпискомЗначений(ByVal ТекстоваяСтрока As String, ByRef ПерваяЯчейка As Range)
    Dim ra As Range, ДлинаСтроки As Long
    ДлинаСтроки = Len(ТекстоваяСтрока): If ДлинаСтроки < 1 Or ДлинаСтроки > 9 Then MsgBox "error": Exit Sub

    Set coll = New Collection: Sm "", ТекстоваяСтрока

    Set ra = ПерваяЯчейка.Cells(1).Resize(coll.Count)
    Dim arr(): ReDim arr(1 To coll.Count, 1 To 1): c = 1

    For Each Item In coll
        For i = 1 To ДлинаСтроки: arr(c, 1) = Item: Next: c = c + 1
    Next
    ra.Value = arr    ' переносим массив на лист
    ra.EntireColumn.AutoFit
End Sub

Sub Пример()
    ЗаполнитьЯчейкиСпискомЗначений "abcde", Worksheets.Add.Cells(2, 2)
    ЗаполнитьЯчейкиПерестановками "12345", [e4]
End Sub
Запустите макрос Пример

Есть и другие, более эффективные и быстрые алгоритмы.
Но для строк небольшой длины и этот работает неплохо.


Если Вам нужно получить только уникальные перестановки,

(например, для такого варианта)
Код:
Sub Пример()
    ЗаполнитьЯчейкиСпискомЗначений "aaab", Worksheets.Add.Cells(2, 2)
    ЗаполнитьЯчейкиПерестановками "12122", [e4]
End Sub
то используйте следующий вариант процедуры Sm:

Код:
Sub Sm(AlreadyS As String, S As String)
    On Local Error Resume Next
    If Len(S) = 1 Then p = AlreadyS & S: coll.Add p, p & "a": Exit Sub
    For i = 1 To Len(S): Sm AlreadyS + Mid$(S, i, 1), Left$(S, i - 1) & Mid$(S, i + 1): Next
End Sub
EducatedFool вне форума
Старый 02.01.2009, 11:09   #3
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Цитата:
Сообщение от cent Посмотреть сообщение
Необходимо создать модуль, который будет генерировать все возможные перестановки элементов...

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

По поводу нужных алгоритмов - в Интернете их множество (в том числе и на VB)

Но для решения данной задачи лучше использовать алгоритмы без рекурсии, - такие как, например, этот
Осталось только найти аналог этого кода на VB.

Готовые алгоритмы можно поискать здесь

Я же взял за основу код из этой темы.

Последний раз редактировалось EducatedFool; 15.12.2010 в 20:57.
EducatedFool вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Генератор паролей pali4ev Общие вопросы Delphi 6 24.12.2008 18:54
генератор перестановок Narkotik Помощь студентам 4 26.11.2008 05:15
Генератор?? Нестер Софт 5 10.07.2008 13:32
Генератор warlok Общие вопросы Delphi 3 30.05.2008 00:53
поиск кратчайшей сортировки, с минимальным кол-вом перестановок sad8c Помощь студентам 9 14.12.2007 10:23