Форум программистов, компьютерный форум, киберфорум
fever brain
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Комбинаторика

Запись от fever brain размещена 14.04.2020 в 15:09
Показов 2512 Комментарии 0


Программа XComb и несколько алгоритмов на VB..

Как работает программа XComb
Это программа родилась благодаря созданной теме на киберфоруме.
Комбинаторика, из заданных цифр нужно составить все возможные четырехзначные комбинации
Итак. Необходимо найти 4 элемента из 10. Пусть это будет 0, 1, 2, 3.. 9
Что для этого потребуется ?
Нужно перебрать все эти элементы.
1 2 3 0, 1 2 3 4, 1 2 3 5, 1 2 3 6 ....
Для этого потребуется два алгоритма из раздела комбинаторики
это двоичная перестановка и индексная перестановка.

Двоичная перестановка.
Это когда имеется известное количество нулей и едениц
из них нужно найти все варианты перестановок
в моем случае это 10 элементов из них интересуют какие-либо 4
значит 4 против 6 -пусть эти 4 элемента будут нулями.
Перечисления будут такого вида
0000111111, 0001011111, 0001101111, 0001110111... до 1111110000
Количество таких комбинаций можно вычислить по формуле:
max = max * N / (N - ЧислоНулей) где первая N это число нулей +1 а последняя N это сумма 0 и 1
тоесть для ряда из 0,1,2,3,4,5,6,7,8,9 первая выборка будет 0,1,2,3.
четвертая выборка это 0,1,2,6 а последняя выборка будет 7,8,9,0
Теперь еще потребуются перестановки каждого получившегося варианта
для этого потребуется индексная перестановка.

Индексная перестановка.
Рассмотрим к примеру элемент 7,8,9,0 - первый индекс=7, последний=0
если переставлять только индексы этого элемента то будет ряд такого вида
(последние три) ...9 7 8 0, 9 8 0 7, 9 8 7 0.
Всего 24 варианта. Но так-как в двоичной перестановке было 210 вариантов, значит
полное число вариантов будет 210 * 24 = 5040.
Если изначальные элементы не были уникальными тоесть были повторы
то это число будет меньше.

В программе можно вводить любые символы

Нажмите на изображение для увеличения
Название: 1.jpg
Просмотров: 3541
Размер:	49.0 Кб
ID:	6110


Отдельные слова или предложения

Нажмите на изображение для увеличения
Название: 2.jpg
Просмотров: 3524
Размер:	60.0 Кб
ID:	6111


Перед обработкой переменная текстового поля подчищается,
убираются лишние разделители и пробелы


Нажмите на изображение для увеличения
Название: 3.jpg
Просмотров: 1214
Размер:	55.0 Кб
ID:	6120

и кстати, никогда об этом не задумывался -этими выражениями можно оперировать

Теперь алгоритмы:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
Sub Пример_использования_Combinations()
    '
    'В данном примере указанны 5 значений и из них нужно найти все варианты из 3-х элементов
    '
    Dim v, w
    w = Combinations("A,B,C,D,E", 3)
    For Each v In w
        Debug.Print v
    Next
End Sub
 
Sub Пример_использования_Perm()
    '
    'Перебор всех возможных вариантов от 0 до указанного N..
    '
    Dim v, i&, j&
    v = Perm(4) '-- В перестановках будут значаться цифры   ..0, 1, 2, 3
    For i = 0 To UBound(v, 1) 'Перечисления 1-го измерения
        Debug.Print
        For j = 0 To UBound(v, 2) 'Перечисления каждого элемента 2-го измерения
            Debug.Print v(i, j);
        Next
    Next
    
End Sub
 
Sub Пример_использования_PermBin()
    '
    'Перебор всех возможных вариантов из определенного количества 0 и 1
    '
    Const _
    Нулей = 4, _
    Едениц = 6, _
    Сумма = Нулей + Едениц
    
    Dim v, i&, j&, s$, jj&
    
    v = PermBin(Нулей, Едениц) 'Обращаемся к двоичной перестановке, и получаем массив
 
    For i = j To UBound(v, 1) 'Перебор элементов 1-го измерения, в каждом элементе,  элементы второго
    
        s = String(Сумма, "1") 'Создаем строку длиной суммы элементов (можно любые знаки использовать)
        
        For j = 0 To UBound(v, 2) 'Перебор элементов 2-го измерения, в каждом элементе, индекс знакоместа "0"
        
            Mid$(s, v(i, j) + 1, 1) = "0" '? +1 В массиве самый нижний индекс = 0, в строке он = 1 (так-же можно ставить любой знак)
        Next
        Debug.Print s
        jj = jj + 1: If jj = 10 Then Stop
    Next
 
End Sub
 
 
Function PermBin(ByVal n0&, ByVal n1&) As Long()
    '
    'Двоичная перестановка
    'Создает двумерный массив, в каждом индексе которого, комбинация из адресов пустых ячеек тоеть нулей
    'Где наименьшая позиция =0 а наибольшая это сумма (n0+n1)-1
    'Арг: n0 - Количество нулей // n1 - Количество едениц
    '
    Dim sum&, ind&, i&, j&, max&, ls&()
    sum = n0 + n1: max = 1
    For i = n0 + 1 To sum
        max = max * i / (i - n0)
    Next
    ReDim ls&(max - 1, n0 - 1), p&(1 To n0), mx&(1 To n0)
    For i = 1 To n0: p(i) = i - 1: mx(i) = (sum - Abs(i - n0)) - 1: Next
    Do: DoEvents
        For i = 0 To n0 - 1
            ls(ind, i) = p(i + 1)
        Next
        ind = ind + 1
        For i = n0 To 1 Step -1
            If p(i) < mx(i) Then
                p(i) = p(i) + 1
                If i < n0 Then For j = i To n0 - 1: p(j + 1) = p(j) + 1: Next
                Exit For
            End If
        Next
    Loop While i > 0
    PermBin = ls
End Function
 
 
Function Perm(ByVal Count&)
    '
    'Индексная перестановка
    'Создает двумерный массив, в каждом индексе которого, комбинация из перестановок значений
    'изначально указанных по возрастанию. Где наименьший=0 а наибольший = Count-1
    'Арг: Count - Количество значений
    '
    
    Dim i&, j&, f&, t&
    Static a&(), q&(), b As Boolean
    If Not b Then
        ReDim q(1 To Count): b = True: t = 1
        For i = 1 To Count: q(i) = i - 1: t = t * i: Next
        ReDim a(t - 1, Count - 1) As Long
        Do: DoEvents: If bCancel Then b = False: Exit Function
            For i = 0 To Count - 1: a(j, i) = q(i + 1): Next: j = j + 1
        Loop While Perm(Count)
        Perm = a: b = False: Exit Function
    End If
 
    For j = Count - 1 To 1 Step -1
        If q(j) < q(j + 1) Then Exit For
    Next
    If j Then
        For i = Count To j + 1 Step -1
            If q(j) < q(i) Then f = q(j): q(j) = q(i): q(i) = f: Exit For
        Next
        Perm = j
    End If
    t = Count: For i = j + 1 To (Count + j) \ 2: f = q(i): q(i) = q(t): q(t) = f: t = t - 1: Next
End Function
 
Function Combinations(ByVal Text$, Optional ByVal Count&, Optional ByVal Delemiter$ = ",", Optional ByVal ProgBarObject As Object) As String()
    '
    'Создает список из вариантов слов (букв или цифр) которые указаны в аргументе Text через разделитель
    'Арг:Text - текст с разделителями // Count - Число возможных элементов // Delemiter = Разделитель
    '
    Dim i&, j&, ii&, jj&, s$, sb$, ch$, uv&, uw&, cur&, b As Boolean
    Dim q$(), u&, a$(), aa$(), result$()
    Dim v, w
    b = Not ProgBarObject Is Nothing
    If Text <> "" Then
        ch = Chr(0)
        q = Split(Text, Delemiter): u = UBound(q)
        If ((Count - 1) > u) Or (Count = 0) Then Count = u + 1
        v = PermBin(Count, u - Count + 1)
        w = Perm(Count)
        If bCancel Then Exit Function
        uv = UBound(v): uw = UBound(w)
        ReDim a(Count - 1): aa = a
        If b Then ProgBarObject.max = (uv + 1) * (uw + 1)
        For i = 0 To uv
            For ii = 0 To Count - 1
                a(ii) = q(v(i, ii))
            Next
            
            For j = 0 To uw
                For jj = 0 To Count - 1
                    aa(jj) = a(w(j, jj))
                Next
                s = ch & Join(aa, Delemiter)
                If InStr(sb, s) = 0 Then
                    sb = sb & s
                    DoEvents: If bCancel Then Exit Function
                    If b Then ProgBarObject.Value = cur: cur = cur + 1
                End If
            Next
        Next
        result = Split(Mid$(sb, 2), ch)
        qSortS result
        Combinations = result
        If b Then ProgBarObject.max = cur
    End If
End Function
 
 
Sub qSortS(a$(), Optional ByVal lb& = -1, Optional ByVal ub&)
    '
    'Быстрая сортировка текстового списка
    '
    Dim i&, j&, s$, w$
    If lb < 0 Then lb = LBound(a): ub = UBound(a)
    i = lb: j = ub: s = a((i + j) \ 2)
    Do Until i > j: Do While a(i) < s: i = i + 1: Loop: Do While a(j) > s: j = j - 1: Loop
        If (i <= j) Then w = a(i): a(i) = a(j): a(j) = w: i = i + 1: j = j - 1
    Loop
    If lb < j Then qSortS a, lb, j
    If i < ub Then qSortS a, i, ub
End Sub
С уважением Александр (fever brain)
Почта: fever.brain@yandex.ru
Яндекс-деньги: https://money.yandex.ru/to/410012701950682
Вложения
Тип файла: rar X-Comb [export].rar (901.9 Кб, 1373 просмотров)
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru