Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 12.01.2017
Сообщений: 4

В поисках панграмм [excel, vba]

12.01.2017, 20:51. Показов 2219. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
ПРИВЕТСТВИЕ

ЧЕГО МЫ ХОТИМ?

На входе имеем базу слов, на выходе – все возможные по условиям панграммы.

УСЛОВИЯ

1. Панграммы ищем для n букв (первостепенно – 33).
2. Все буквы в конечном наборе слов предложении встречаются ровно по 1 разу.
3. Исходная база содержит слова с повторяющимися буквами и/или всякими ненужными символами (какими конкретно – не известно).

МОЙ ВКЛАД

1. Нашел формулу массива для первоначальной сортировки базы:
{=ИЛИ((ДЛСТР(A2)-ДЛСТР(ПОДСТАВИТЬ(СТРОЧН(A2);СИМВОЛ(СТРОК А($1:$255));"")))>1)}
Для слов с повторяющимися буквами выдает ИСТИНА. Далее сортируем, все строки с ИСТИНА в расход, оставляем одни только ЛОЖИ.

2. Нашел макрос на очищение нашей уже обрезанной базы от всякой нечисти - достаточно указать список лишних символов. Проблема: база большая, какой там конкретно мусор – не известно. Искал макрос который бы выводил список всех символов (по 1 шт), имеющихся на листе, не нашел.

3. Подумал над алгоритмом для работы с результирующей базой.

ВОЗМОЖНЫЙ АЛГОРИТМ

1. Выводим все буквы слова функцией ПСТР.
2. Создаем двоичный код каждого слова функцией СЧЁТЕСЛИ.
3. Переводим в десятичную систему счисления, поочередно умножая на 2^m (m<33) и затем суммируя. Можно, конечно, объединить все 0 и 1 в громоздкое 33-ёхзначное число, которое потом перегнать функцией ДВВДЕС. Имеем столбец #1 с.. назовем это численной записью числа.
4. Сортируем базу слов по столбцу #1. Имеем численную запись чисел по возрастанию/убыванию.
5. Моя остановочка.

Дело за малым – научиться выделять из столбца #1 диапазон слов с разными буквами, сумма численных значений которых равна (2^33)-1 = 8589934591 (для 33-ёх букв, не говоря уже о количестве вариаций для 32, 31 и т.д.)

ЛЁД ТРОНУЛСЯ

Нашел такую весчь, называется подбор слагаемых под нужную сумму. Является частным случаем «задачи о рюкзаке». Наиболее оптимальные на мой беглый взгляд алгоритмы обитают тута (http://www.excelworld.ru/forum/10-5196-1). Вот если бы эту штуку как-то применить в нашей задаче. Описанный мною выше возможный алгоритм можно упростить до записи слов в двоичном коде. Далее:

1. Берем первое слово, сверяем с каждым на наличие одинаковых букв (единичек). Отбираем массив #1(1) слов с буквами, которых нет в нашем первом слове.
2. Берем первое слово из массива #1(1), сверяем с каждым из массива #1(1) на наличие одинаковых букв (единичек). Отбираем массив #2(1) слов с буквами, которых нет в нашем первом слове из массива #1(1).
3. Повторяем операцию до тех пор, пока конечный массив не превратится в слово. Суммируем двоичный код получившейся выборки и проверяем на равенство 11…11 (33 шт).
4. Возвращаемся на массив уровнем выше (предпоследний), берем оттуда второе слово и делаем все то же самое (опускаемся вниз, проверяем на равенство новую выборку). Если слов в нем больше двух, повторяем операцию с третьим и так далее.
5. Продолжаем последовательно подниматься до массива #1(1), где выбираем уже второе слово, вновь опускаемся до конечного «массива» (одно слово), вновь последовательно поднимаемся и опускаемся; возвратившись в массив #1(1), берем третье слово и так далее.
6. Проверив все слова из массива #1(1), возвращаемся в исходную базу, берем 2 слово, получаем массив #1(2) и работаем с ним аналогично.

Перевод в десятичную СС – это просто сокращение записи. Можно назначить буквам «вес», например 1-33 и начать искать слагаемые под сумму 33*(33+1)/2 = 561, но т.к. они разнятся всего на единицу, ложных вариантов будет как минимум 90%. Можно назначить первой букве вес 10^-16, 17-ой – 1, последней – 10^16. В промежутке известно что. Ложные варианты сократятся на порядок. 10 можно заменить и на 100, и на 1000, но я не уверен, будет ли алгоритм подбора слагаемых под сумму корректно обрабатывать такие данные.

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

Еще нашел макросы на расположение букв в слове в алфавитном порядке. Модернизированную таким образом базу можно отсортировать в алфавитном порядке, имеем, таким образом, 33 группы. Далее можно сгруппировать слова по наличию сочетаний АБ – ЮЯ (528), АБВ – ЭЮЯ (5456), АБВГ – ЫЭЯЮ (40920) и т.д. (исходя из формулы N!/((N – M*K)!*((K!)^M)), и уже это использовать как условие для запрета совмещения тех или иных слов.

Если все гораздо проще, то да простит меня Оккам!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.01.2017, 20:51
Ответы с готовыми решениями:

Vba excel windows и vba excel Mac Os - Макинтош корявит шрифт
Всем привет, столкнулся с такой ситуацией. Макросы написаны на Excel 2016 Windows. Когда файл открывается и сохраняется на маке, весь...

Функциия excel в функции excel на vba
С помощью мастера записи матросов получил следующую функцию ActiveCell.FormulaR1C1 = &quot;=IFERROR...

EXCEL VBA
Всем привет) Не могу сделать((( 1. Автозаполнение столбика n числами из последовательного массива пользователя. 2. В ячейки вводятся...

19
 Аватар для yutrans
142 / 125 / 50
Регистрация: 10.11.2011
Сообщений: 622
13.01.2017, 08:22
http://www.excelworld.ru/forum/10-31867-1
0
13.01.2017, 08:40

Не по теме:

Цитата Сообщение от magNstr rYJIon Посмотреть сообщение
ЧЕГО МЫ ХОТИМ?
Кто "мы" ?

0
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
13.01.2017, 13:41
Генератор панграмм на основе Генератора анаграмм(
Ускорить работу программы
)
Кликните здесь для просмотра всего текста
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
Option Explicit
Option Base 1
Dim Dic As Object, razmer&
 
Sub Pangramma()
    Dim i%, kolbukv&, stroka$, sim, slovo$, predlojenie$, schet&, vX
    ReDim sim(3)
    stroka = [A5]
    stroka = LCase(stroka) ' Для дальнейшего избавления от дубликатов букв в разном регистре
    Bukvy_Cyrillica stroka, sim
    kolbukv = UBound(sim)
    razmer = kolbukv
    Application.ScreenUpdating = False
    ThisWorkbook.Sheets(1).Columns("B:B").ClearContents
    Set Dic = CreateObject("Scripting.Dictionary")
    SlovoRecurs predlojenie, slovo, sim  ' Первый вызов SlovoRecurs, predlojenie="", Slovo="", массив  Sim содержит все буквы
    If Dic.Count = 0 Then
        MsgBox "Не найдено."
    Else
        For Each vX In Dic.Keys
            schet = schet + 1
            Cells(schet, 2) = vX
        Next
        Columns("B:B").Sort Columns("B:B")
    End If
    Set Dic = Nothing
End Sub
 
Sub SlovoRecurs(predlojenie$, slovo$, sim)
    Dim i&, j&, k&, UBoundSim&, LenSlovo&, sTemp, Slovo2$, predlojenie2$, Usl As Boolean
    LenSlovo = Len(Replace(predlojenie, " ", "")) + Len(slovo)
    UBoundSim = UBound(sim)
    For i = 1 To UBoundSim
        Usl = False
        If slovo = "" Then
           Usl = Slovo1bukva(sim(i))
        Else
           Usl = Application.CheckSpelling(slovo & sim(i))
        End If
        If LenSlovo = razmer - 1 Then
            If Usl Then
                predlojenie = predlojenie & slovo & sim(i)
                Dic(predlojenie) = 0&
            End If
        ElseIf LenSlovo > razmer - 1 Then
        Else
            ReDim sTemp(1)
            k = 0
            For j = 1 To i - 1
                k = k + 1
                ReDim Preserve sTemp(k)
                sTemp(k) = sim(j)
            Next j
            For j = i + 1 To UBoundSim
                k = k + 1
                ReDim Preserve sTemp(k)
                sTemp(k) = sim(j)
            Next j
            If Usl Then
                predlojenie2 = predlojenie & slovo & sim(i) & " "
                Slovo2 = ""
                '2,3, ...n вызов SlovoRecurs по каждой ветви с разной(-ными) начальной(-ными) буквами Slovo2
                'массив  sTemp содержит оставшиеся буквы на каждой ветви (разные буквы в начале)
                ' на каждом этапе (разная длина слова сформирована)
                SlovoRecurs predlojenie2, Slovo2, sTemp
            End If
            predlojenie2 = predlojenie
            Slovo2 = slovo & sim(i)
            '2,3, ...n вызов
            SlovoRecurs predlojenie2, Slovo2, sTemp
        End If
    Next i
End Sub
 
Sub Bukvy_Cyrillica(S, sim)
    Dim i%, k%, B$, DicB
    Set DicB = CreateObject("Scripting.Dictionary")
    For i = 1 To Len(S)
        B = Mid(S, i, 1)
        Select Case B
            Case "а" To "я", "ё"
                If Not DicB.Exists(B) Then ' Для избавления от дубликатов букв
                    DicB(B) = 0&
                    k = k + 1
                    ReDim Preserve sim(k)
                    sim(k) = B
                End If
        End Select
    Next i
    Set DicB = Nothing
End Sub
 
Function Slovo1bukva(S) As Boolean
    Slovo1bukva = True
    Select Case S
        Case "я" '- местоимение;
        Case "в", "к", "о", "с", "у" '   - предлог;
        Case "и", "а" ' - союз;
        'Case "б" '- частица (если б, я б в рабочие пошел и т. д.) ;
        'Case "а", "о", "э", "у"  '-междометие
        Case Else
            Slovo1bukva = False
    End Select
End Function

Application.CheckSpelling определяет каки- то неизвестные двухбуквенные слова (например "ид") - претензии предъявляйте к компании Microsoft.
Для 33 букв может не хватить оперативной памяти.
Время перебора ветвей, веточек и листьев дерева всех комбинаций 33 букв даже не оценивал, оно может быть гигантским.

К тому же задача со всеми 33 буквами кириллицы может быть не решаема в принципе, так как будет ощущаться нехватка гласных.
Вложения
Тип файла: rar Генератор_панграмм.rar (25.3 Кб, 3 просмотров)
0
0 / 0 / 0
Регистрация: 12.01.2017
Сообщений: 4
13.01.2017, 20:00  [ТС]
yutrans, благодарю. Исключительно на этом форуме модератор почему-то удалил ссылки на прочие ресурсы, где я разместил аналогичный пост. Или необходимо ссылаться непосредственно на темы?

SoftIce, Билли Миллиган и компания.

KoGG, спасибо за содействие! Макрос, к сожалению, как Вы уже подчеркнули, далеко не самый оптимальный.

Цитата Сообщение от KoGG Посмотреть сообщение
К тому же задача со всеми 33 буквами кириллицы может быть не решаема в принципе, так как будет ощущаться нехватка гласных.
Вот тут имеются базы всевозможных слов. Взял оттуда первые две, удалил все слова, в которых буквы повторяются, отсортировал по количеству гласных, удалил все слова с 3 и более гласными, отсортировал оставшиеся два диапазона по длине слов, подсчитал их количество.

И уже после всего этого я твердо могу заявить, что с Вами не согласен.
Вложения
Тип файла: zip zdf_pldf_sort.zip (65.1 Кб, 4 просмотров)
0
14.01.2017, 10:11

Не по теме:

Цитата Сообщение от magNstr rYJIon Посмотреть сообщение
Билли Миллиган
Это ваш кумир?

0
0 / 0 / 0
Регистрация: 12.01.2017
Сообщений: 4
14.01.2017, 21:39  [ТС]
SoftIce, это наш фанат.
0
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
17.01.2017, 12:03
Генератор панграмм на Вашей базе слов.
Быстродействие тоже низкое, запустил для 33 букв и в отладочном режиме смотрю текущие промежуточные комбинации.
Несколько минут уходит только на 1 слово верхнего уровня, несмотря на то, что начинаю тестовый перебор с 5-ти буквенных слов (для оптимизации).
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
Option Base 1
Sub Pangramma_na_baze()
    Const MaxKolPangramm = 1 ' Чтобы не набирать огромное число комбинаций слов для среднего числа букв
    Dim i&, ii%, j%, k%, A, B, PanKol%, strokaVhod$, KolSlov&, S$, Z$, Novoe As Boolean
    Dim KolSlovStolb&(10), Pangramma$(MaxKolPangramm), Predlojenie$(16), SlovoRow&(0 To 16), SlovoCol%(0 To 16)
    Dim Obrazec() As Boolean, OstatokObr() As Boolean, OstatokObrOld(), Tek() As Boolean
    ReDim Obrazec(33), OstatokObr(33), OstatokObrOld(0 To 33), Tek(33)
    strokaVhod = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" ' "ад и ёж" '"а я ёж" ' "абвгдеёжзя" '"абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
    strokaVhod = LCase(strokaVhod) ' работаем со строчными буквами
    ' Цифрограмма слова это массив от 1до 33, 1-32 = а-я, 33=ё . True если есть буква в слове.
    Cifrogramma strokaVhod, Obrazec
    With Worksheets("Baza")
        ' Массив с базой слов. Номер столбца от 1 до 10 равен числу букв в словах. Каждый столбец упорядочен по алфавиту.
        A = .UsedRange.Value
        For j = 1 To 10
            KolSlovStolb(j) = .Cells(.Rows.Count, j).End(xlUp).Row
        Next
    End With
    ReDim B(UBound(A), 10) ' Массив массивов цифрогамм слов из базы
    For j = 1 To 10
        For i = 1 To KolSlovStolb(j)
            ReDim Tek(33)
            Cifrogramma A(i, j), Tek
            B(i, j) = Tek
        Next i
    Next j
    '--- перебор слов в базе------------
    For PanKol = 1 To MaxKolPangramm
        OstatokObr = Obrazec
        KolSlov = 0
        Erase Predlojenie
        'For k = 0 To 16: SlovoRow(k) = 0: SlovoCol(k) = 10: Next k
        '##############################################
        For k = 0 To 16: SlovoRow(k) = 0: SlovoCol(k) = 5: Next k ' оптимизация для 33 букв
        KolSlovStolb(1) = 0: KolSlovStolb(2) = 0 ' оптимизация для 33 букв
        '##############################################
        Do
            'For j = SlovoCol(KolSlov) To 1 Step -1
            For j = SlovoCol(KolSlov) To 1 Step -1  ' оптимизация для 33 букв
                ii = IIf(j = SlovoCol(KolSlov), SlovoRow(KolSlov) + 1, 1)
                For i = ii To KolSlovStolb(j)
                    If ObrazecMinusSlovo(OstatokObr, B(i, j), Tek) Then
                       ' Stop '+++++++++++
                        SlovoRow(KolSlov) = i
                        SlovoCol(KolSlov) = j
                        OstatokObrOld(KolSlov) = OstatokObr
                        OstatokObr = Tek
                        KolSlov = KolSlov + 1
                        Predlojenie(KolSlov) = A(i, j)
                        '++++++++++++++++
                        Debug.Print KolSlov,
                        For k = 1 To KolSlov
                            Debug.Print Predlojenie(k) & " ";
                        Next k
                        Debug.Print
                        '++++++++++++++++
                        If NeOstalosBukv(OstatokObr) Then
                            S = ""
                            For k = 1 To KolSlov
                                S = S & Predlojenie(k) & " "
                            Next k
                            S = Trim(S)
                            Novoe = True
                            For ii = 1 To PanKol - 1
                                If Pangramma(ii) = S Then Novoe = False: Exit For
                            Next ii
                            If Novoe Then
                                For k = 1 To KolSlov
                                    Pangramma(PanKol) = Predlojenie(k)
                                Next k
                                Pangramma(PanKol) = S
                                Exit Do
                            End If
                        End If
                    End If
                    '+++++++++++++++++++++
                    DoEvents  '+++++++++
                    '+++++++++++++++++++++
                Next i
                'Stop '+++++++++++
            Next j
            SlovoRow(KolSlov) = 0
            'SlovoCol(KolSlov) = 10
            '##############################################
            SlovoCol(KolSlov) = 5 ' оптимизация для 33 букв
            '##############################################
            KolSlov = KolSlov - 1
            If KolSlov < 0 Then Exit Do
            OstatokObr = OstatokObrOld(KolSlov)
        Loop
    Next PanKol
    '-----------------------------------
    S = ""
    For i = 1 To MaxKolPangramm
        S = S & Pangramma(i) & vbCrLf
    Next
    'MsgBox S
    Debug.Print S
End Sub
 
Function ObrazecMinusSlovo(ByVal Obrazec, Slovo, Ostatok) As Boolean
    Dim i%
    ReDim Ostatok(33)
    Ostatok = Obrazec
    For i = 1 To 33
        If Obrazec(i) = False And Slovo(i) Then
            Ostatok = Obrazec
            Exit Function
        ElseIf Obrazec(i) And Slovo(i) Then
            Ostatok(i) = False
        End If
    Next
    ObrazecMinusSlovo = True
End Function
 
Function NeOstalosBukv(Obrazec) As Boolean
    Dim i%
    For i = 1 To 33
        If Obrazec(i) Then Exit Function
    Next
    NeOstalosBukv = True
End Function
 
Sub Cifrogramma(S, Obrazec)
    Dim i%, B$
    For i = 1 To Len(S)
        B = Mid(S, i, 1)
        Select Case B
            Case "ё"
               Obrazec(33) = True
            Case "а" To "я", "ё"
               Obrazec(Asc(B) - 223) = True
        End Select
    Next i
End Sub
Вложения
Тип файла: rar Генератор_панграмм_на_базе_0.rar (167.8 Кб, 3 просмотров)
0
6180 / 945 / 313
Регистрация: 25.02.2011
Сообщений: 1,381
Записей в блоге: 1
17.01.2017, 13:44
Цитата Сообщение от KoGG Посмотреть сообщение
Генератор панграмм на Вашей базе слов.
Не могу открыть файл (антивирус на работе не пропускает xlsm файлы)
KoGG, удалось ли Вам составить панграмму из 33 букв, если да, то сколько на все это ушло времени?
0
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
17.01.2017, 15:11
Не удалось.
Задача явно для суперкомпьютеров.
Вот второй вариант кода, с небольшим ускорением по частотности букв и прочими.
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
Option Base 1
Dim Ch
Sub Pangramma_na_baze()
    Const MaxKolPangramm = 1 ' Чтобы не набирать огромное число комбинаций слов для среднего числа букв
    Dim i&, ii%, j%, k%, kk&, A, B, PanKol%, strokaVhod$, KolSlov&, S$, Z$, Novoe As Boolean
    Dim KolSlovStolb&(10), Pangramma$(MaxKolPangramm), Predlojenie$(16), SlovoRow&(0 To 16), SlovoCol%(0 To 16)
    Dim Obrazec() As Boolean, OstatokObr() As Boolean, OstatokObrOld(), Tek() As Boolean
    ReDim Obrazec(33), OstatokObr(33), OstatokObrOld(0 To 33), Tek(33)
    strokaVhod = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" ' "ад и ёж" '"а я ёж" ' "абвгдеёжзя" '"абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
    strokaVhod = LCase(strokaVhod) ' работаем со строчными буквами
    ' Цифрограмма слова это массив от 1до 33, 1-32 = а-я, 33=ё . True если есть буква в слове.
    Cifrogramma strokaVhod, Obrazec
    'Номера позиций в цифрограмме в порядке понижения частотности букв
    ' о е а и н т с р в л к м д п у я ы ь г з б ч й х ж ш ю ц щ э ф ъ ё
    Ch = Array(15, 6, 1, 9, 14, 19, 18, 17, 3, 12, 11, 13, 5, 16, 20, 32, 28, 29, 4, 8, 2, 24, 10, 22, 7, 25, 31, 23, 26, 30, 21, 27, 33)
    With Worksheets("Baza")
        ' Массив с базой слов. Номер столбца от 1 до 10 равен числу букв в словах. Каждый столбец упорядочен по алфавиту.
        A = .UsedRange.Value
        For j = 1 To 10
            KolSlovStolb(j) = .Cells(.Rows.Count, j).End(xlUp).Row
        Next
    End With
    ReDim B(UBound(A), 10) ' Массив массивов цифрогамм слов из базы
    For j = 1 To 10
        For i = 1 To KolSlovStolb(j)
            ReDim Tek(33)
            Cifrogramma A(i, j), Tek
            B(i, j) = Tek
        Next i
    Next j
    '--- перебор слов в базе------------
    For PanKol = 1 To MaxKolPangramm
        OstatokObr = Obrazec
        KolSlov = 0
        Erase Predlojenie
        'For k = 1 To 16: SlovoRow(k) = 0: SlovoCol(k) = 10: Next k
        '##############################################             оптимизация для 33 букв
        For k = 1 To 16: SlovoRow(k) = 0: SlovoCol(k) = 5: Next k ' оптимизация для 33 букв
        KolSlovStolb(1) = 0: KolSlovStolb(2) = 0            ' оптимизация для 33 букв
        '############################################## оптимизация для 33 букв
        If PanKol = 1 Then SlovoRow(0) = 0: SlovoCol(0) = SlovoCol(1)
        Do
            For j = SlovoCol(KolSlov) To 1 Step -1
                ii = IIf(j = SlovoCol(KolSlov), SlovoRow(KolSlov) + 1, 1)
                For i = ii To KolSlovStolb(j)
                    If EstVObrazce(OstatokObr, B(i, j)) Then
                        ObrazecMinusSlovo OstatokObr, B(i, j), Tek
                       ' Stop '+++++++++++
                        SlovoRow(KolSlov) = i
                        SlovoCol(KolSlov) = j
                        OstatokObrOld(KolSlov) = OstatokObr
                        OstatokObr = Tek
                        KolSlov = KolSlov + 1
                        Predlojenie(KolSlov) = A(i, j)
                        If NeOstalosBukv(OstatokObr) Then
                            S = ""
                            For k = 1 To KolSlov
                                S = S & Predlojenie(k) & " "
                            Next k
                            S = Trim(S)
                            Novoe = True
                            For ii = 1 To PanKol - 1
                                If Pangramma(ii) = S Then Novoe = False: Exit For
                            Next ii
                            If Novoe Then
                                For k = 1 To KolSlov
                                    Pangramma(PanKol) = Predlojenie(k)
                                Next k
                                Pangramma(PanKol) = S
                                Exit Do
                            End If
                        End If
                    End If
                    '+++++++++++++++++++++
                    DoEvents  '+++++++++
                    '+++++++++++++++++++++
                Next i
                'Stop '+++++++++++
            Next j
            kk = kk + 1
            '++++++++++++++++
            If kk Mod 10 = 0 Then
                Debug.Print kk,
                For k = 1 To KolSlov
                    Debug.Print Predlojenie(k) & " ";
                Next k
                Debug.Print
            End If
            '++++++++++++++++
            SlovoRow(KolSlov) = 0
            'SlovoCol(KolSlov) = 10
            '############################################## ' оптимизация для 33 букв
            SlovoCol(KolSlov) = 5 ' оптимизация для 33 букв
            '############################################## ' оптимизация для 33 букв
            KolSlov = KolSlov - 1
            If KolSlov < 0 Then Exit Do
            OstatokObr = OstatokObrOld(KolSlov)
            '+++++++++++++++ ' Ограничитель итераций
            If kk > 100000 Then End
            '+++++++++++++++
        Loop
    Next PanKol
    '-----------------------------------
    S = ""
    For i = 1 To MaxKolPangramm
        S = S & Pangramma(i) & vbCrLf
    Next
    'MsgBox S
    Debug.Print S
End Sub
 
Function EstVObrazce(Obrazec, Slovo) As Boolean
    Dim i%
    For i = 1 To 33
        If Obrazec(Ch(i)) = False And Slovo(Ch(i)) Then Exit Function
    Next
    EstVObrazce = True
End Function
 
Function ObrazecMinusSlovo(Obrazec, Slovo, Ostatok) As Boolean
    Dim i%
    Ostatok = Obrazec
    For i = 1 To 33
        If Obrazec(i) And Slovo(i) Then Ostatok(i) = False
    Next
    ObrazecMinusSlovo = True
End Function
 
Function NeOstalosBukv(Obrazec) As Boolean
    Dim i%
    For i = 33 To 1 Step -1
        If Obrazec(i) Then Exit Function
    Next
    NeOstalosBukv = True
End Function
 
Sub Cifrogramma(S, Obrazec)
    Dim i%, B$
    For i = 1 To Len(S)
        B = Mid(S, i, 1)
        Select Case B
            Case "ё"
               Obrazec(33) = True
            Case "а" To "я", "ё"
               Obrazec(Asc(B) - 223) = True
        End Select
    Next i
End Sub
и файл с базой
Не дождался смены 1-го слова , десятки минут работает.
Может быть еще и можно немного ускорить, но большое время работы сулят сами законы комбинатортики .
Вложения
Тип файла: rar Генератор_панграмм_на_базе_1.rar (121.5 Кб, 4 просмотров)
0
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
17.01.2017, 15:25
Причем в известных панграммах
https://www.artlebedev.ru/kovodstvo/sections/33/
буквы повторяются, а здесь по условиям задачи в панграмме каждая буква должна встречаться только 1 раз.
И база слов, которую я взял у magNstr rYJIon бедновата, словоформы отсутствуют.
Со всеми падежами и словоформами база разбухнет и работа генератора еще замедлится.
0
6180 / 945 / 313
Регистрация: 25.02.2011
Сообщений: 1,381
Записей в блоге: 1
17.01.2017, 16:11
Цитата Сообщение от KoGG Посмотреть сообщение
но большое время работы сулят сами законы комбинатортики
Если изменить подход к решению, то панграммы находятся достаточно быстро.
Алгоритм, с помощью которого можно найти панграммы я расписал по ссылке из второго поста (нашел более двух десятков панграмм по словарю из 24 тыс слов, но их можно подобрать существенно больше).

Решение делал в полуавтоматическом режиме. Будет время полностью автоматизирую процесс.
0
6180 / 945 / 313
Регистрация: 25.02.2011
Сообщений: 1,381
Записей в блоге: 1
18.01.2017, 02:01
Лучший ответ Сообщение было отмечено Sasha_Smirnov как решение

Решение

26 панграмм, слова в которых не повторяются
Кликните здесь для просмотра всего текста
взбухать дюже съёмщик шляпочный эрг
брюхач въезжий шмыг щёлкнуться эпод
багряность въезд жмых шлёп щучий экю
бег двухэтажный прочь съём шлюз ящик
вождь зряшный кэтч съёмщица убег хлюп
битюг вещь душ пляж съёмочный экзарх
буж вьючный подъёмщик саз шлях эгрет
вошь плюх разъёмщик стяг чуждый эбен
взъехать кряж люэс подгиб шум щёчный
адъюнкт вуз мэр обжёгшийся печь хлыщ
два жгучесть объём хрящ шлюзный эпик
брызжущий ключ подъём снять швах эге
душный звяк плющ съёжить чех эмбарго
баш вздуть съёмцы хрюк щеглячий эпонж
дрязг жучить плюшка съёмный хвощ эфеб
взгляд жечь нэп объёмистый хрущ юшка
многажды съязвить чуб шейх щёлк эпюр
блюмс въехать гуж подщёчный шик эрзя
брюшняк гит жёлчь съездовый щуп эхма
бэр гвоздь пуще съёмка шляхтич южный
вглубь жох пшют разъём эсдек ящичный
вхожий любя пэр съезд шмыгнуть щёчка
жемчуг ксёндз объять прыщ шах элювий
вруб пых съезжий фанг шмяк щёлочь этюд
жгучий мышьяк нюх объезд плащ рёв эст
взахлёб гюйс крыж подъять чинш щец эму

Принцип поиска: после найденной панграммы, слова удаляются из словаря, далее запускается новый поиск.
Если перемешать слова в словаре, то будут найдены другие панграммы.

Во вложении файл с кодом и несколько десятков разных панграмм, найденных по словарю из 24 тыс. слов
Вложения
Тип файла: zip pangramm.zip (3.78 Мб, 5 просмотров)
2
 Аватар для Sasha_Smirnov
5562 / 1370 / 150
Регистрация: 08.02.2009
Сообщений: 4,109
Записей в блоге: 30
18.01.2017, 06:33
Из спойлера развеселили туристская и экономическая:
  • брызжущий ключ подъём снять швах эге
  • душный звяк плющ съёжить чех эмбарго
0
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
18.01.2017, 09:26
M-ch, cамая соль происходит за пределами VBA в стороннем exe приложении.
Где-то видел решения по Симплекс методу и в VB /VBA .
0
6180 / 945 / 313
Регистрация: 25.02.2011
Сообщений: 1,381
Записей в блоге: 1
18.01.2017, 10:53
Цитата Сообщение от KoGG Посмотреть сообщение
cамая соль происходит за пределами VBA в стороннем exe приложении.
Я об этом и писал, нужно составить правильную математическую модель, а затем применить к ней известные подходы для ее решения.

Вместо exe файла можно прикрутить lpsolve, реализованную в виде dll, имеющую доступный из VBA api, но lpsolve давно не обновлялся и работает медленнее

Цитата Сообщение от KoGG Посмотреть сообщение
Где-то видел решения по Симплекс методу и в VB /VBA
Не думаю, что решение симплекс-метода на VB/VBA в чистом виде будет хорошей идеей, как по скорости, так и по качеству. Зачем изобретать велосипед, когда качественное решение сделано в виде готового продукта и реализовано в виде внешней библиотеки, к тому же над ним работали/работают выдающиеся умы.
0
6180 / 945 / 313
Регистрация: 25.02.2011
Сообщений: 1,381
Записей в блоге: 1
18.01.2017, 11:56
Во вложении 306 панграмм найденных по выложенному выше словарю и частотный анализ использования слов в них
Вложения
Тип файла: xlsx Панграммы.xlsx (28.1 Кб, 9 просмотров)
0
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
19.01.2017, 15:01
Алгоритм на уменьшающихся массивах, близкий к описанному magNstr rYJIon ,
но все равно слишком медленный.
Вложения
Тип файла: rar Генератор_панграмм_на_базе_U_1_Ex97.rar (757.6 Кб, 6 просмотров)
1
 Аватар для KoGG
5636 / 1618 / 418
Регистрация: 23.12.2010
Сообщений: 2,426
Записей в блоге: 1
23.01.2017, 16:29
Модифицировал последний алгоритм перебора, поиск в следующем круге по наиболее редкой букве в оставшихся словах.
За 440 с. перебрал всю базу и ничего не нашел.
Затем модифицировал - поиск в ветвях, начинающихся словами, содержащих 1 из 3-х наиболее редких букв в оставшемся массиве слов, и, о чудо, программа нашла первую панграмму за 220 секунд:
обжёгшийся въезд фальц кэтч нюх рым щуп
Вложения
Тип файла: rar Генератор_панграмм_на_базе_U_3_Ex97.rar (652.3 Кб, 5 просмотров)
0
6180 / 945 / 313
Регистрация: 25.02.2011
Сообщений: 1,381
Записей в блоге: 1
30.01.2017, 07:41
В коде из 13го сообщения опечатка (не правильно перечислен алфавит, пропущены буквы "ф" и "ц"), Панграммы из 17 го сообщения не верные

Выкладываю исправленный код, а также 1600 различных панграмм, найденных по словарю из 24 тыс. слов
Вложения
Тип файла: zip pangramm3.zip (3.82 Мб, 8 просмотров)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.01.2017, 07:41
Помогаю со студенческими работами здесь

VBA Excel
Дали брату вот такое задание,я в этом ничего не понимаю,если кто-то поможет сделать задание буду весьма благодарен :)

VBA MS Excel

VBA Excel
Как из формы VBA в Excel c несколькими TextBoxами перенести данные на другой лист в определённые ячейки? и чтобы при следующем заполнении...

MS Excel VBA
Получить новую матрицу путем умножения элементов каждой строки исходной матрицы на наименьший по значению элемент соответствующей строки

VBA Excel
Подскажите пожалуйста, как для трех выделенных ячеек со значениями длин треугольника определить его тип: остроугольный, прямоугольный,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru