Здравствуйте! Есть 4 элемента (A, B, C, D) . Помогите сгенерировать в VBA все возможные комбинации из них в лексикографическом порядке по выбранному числу? Например если по 2, тогда должно быть 12 комбинаций (4!/(4-2)!=12):
AB AC AD BA BC BD CA CB CD DA DB DC
если по 3, тогда должно быть 24 комбинации (4!/(4-3)!=24):
ABC ABD ACB ACD ADB ADC BAC BAD BCA BCD BDA BDC CAB CAD CBA CBD CDA CDB DAB DAC DBA DBC DCA DCB
На самом деле элементов 10, указал меньше для упрощения.
Здравствуйте! Есть 4 элемента (A, B, C, D) . Помогите сгенерировать в VBA все возможные комбинации из них в лексикографическом порядке по выбранному числу? Например если по 2, тогда должно быть 12 комбинаций (4!/(4-2)!=12):
AB AC AD BA BC BD CA CB CD DA DB DC
если по 3, тогда должно быть 24 комбинации (4!/(4-3)!=24):
ABC ABD ACB ACD ADB ADC BAC BAD BCA BCD BDA BDC CAB CAD CBA CBD CDA CDB DAB DAC DBA DBC DCA DCB
На самом деле элементов 10, указал меньше для упрощения.Mexo
По сколько элементов размещать, хотелось бы заказывать в параметрах этой функции(процедуры) при ее вызове. Вообще все гораздо сложнее, а это как бы первый шаг на пути решения задачи. nilem, Спасибо! Попробую разобраться.
По сколько элементов размещать, хотелось бы заказывать в параметрах этой функции(процедуры) при ее вызове. Вообще все гораздо сложнее, а это как бы первый шаг на пути решения задачи. nilem, Спасибо! Попробую разобраться.Mexo
nilem, спасибо, пример генерирует как надо, только долго думает когда выбираю максимальное для моей задачи число элементов (9) и максимальное число размещений (8). Есть ли какой нибудь способ ускорить эту генерацию? Может быть как то сделать цикл на каждый элемент или еще как нибудь...?
nilem, спасибо, пример генерирует как надо, только долго думает когда выбираю максимальное для моей задачи число элементов (9) и максимальное число размещений (8). Есть ли какой нибудь способ ускорить эту генерацию? Может быть как то сделать цикл на каждый элемент или еще как нибудь...?Mexo
Понял, это из-за нехватки ячеек. Еще пришел к выводу что мне будет достаточно перестановок без размещения по количеству элементов. Остановился на таком варианте:
[vba]
Код
Option Explicit Public cnt As Integer
Sub Comb()
Dim InputStr As String Dim OutputStr As String
cnt = 0 OutputStr = "" Sheets("Ëèñò1").Columns(1).ClearContents InputStr = Sheets("Ëèñò1").Range("C2").Value PermSmpl OutputStr, InputStr End Sub
Sub PermSmpl(OutNowStr As String, InNowStr As String)
Dim k As Integer 'length of the input letters Dim i As Integer Dim OutNextStr As String Dim InNextStr As String
If InNowStr = "" Then cnt = cnt + 1 Sheets("Ëèñò1").Cells(cnt, 1).Value = OutNowStr
Else k = Len(InNowStr) For i = 1 To k OutNextStr = OutNowStr & Mid(InNowStr, i, 1) InNextStr = Mid(InNowStr, 1, i - 1) & Mid(InNowStr, i + 1, k - i) PermSmpl OutNextStr, InNextStr Next i End If End Sub
[/vba]
Подскажите как поправить код, чтобы комбинации выводились не на лист а в vba массив?
Понял, это из-за нехватки ячеек. Еще пришел к выводу что мне будет достаточно перестановок без размещения по количеству элементов. Остановился на таком варианте:
[vba]
Код
Option Explicit Public cnt As Integer
Sub Comb()
Dim InputStr As String Dim OutputStr As String
cnt = 0 OutputStr = "" Sheets("Ëèñò1").Columns(1).ClearContents InputStr = Sheets("Ëèñò1").Range("C2").Value PermSmpl OutputStr, InputStr End Sub
Sub PermSmpl(OutNowStr As String, InNowStr As String)
Dim k As Integer 'length of the input letters Dim i As Integer Dim OutNextStr As String Dim InNextStr As String
If InNowStr = "" Then cnt = cnt + 1 Sheets("Ëèñò1").Cells(cnt, 1).Value = OutNowStr
Else k = Len(InNowStr) For i = 1 To k OutNextStr = OutNowStr & Mid(InNowStr, i, 1) InNextStr = Mid(InNowStr, 1, i - 1) & Mid(InNowStr, i + 1, k - i) PermSmpl OutNextStr, InNextStr Next i End If End Sub
[/vba]
Подскажите как поправить код, чтобы комбинации выводились не на лист а в vba массив?Mexo
"Понял, это из-за нехватки ячеек." Ячеек там более 1 млн (и это только в одном столбце!). Просто Integer замените на Long Вот с массивом, который выводится на лист
[vba]
Код
Option Explicit Dim cnt As Long Dim Rez() As String
Sub Comb() Dim InputStr As String, OutputStr As String
cnt = 0: OutputStr = "" Sheets("Лист1").Columns(1).ClearContents InputStr = Sheets("Лист1").Range("C2").Value ReDim Rez(1 To WorksheetFunction.Fact(Len(InputStr)), 1 To 1)
PermSmpl OutputStr, InputStr Range("A1").Resize(cnt).Value = Rez() Erase Rez End Sub
Sub PermSmpl(OutNowStr As String, InNowStr As String) Dim k As Long 'length of the input letters Dim i As Long Dim OutNextStr As String, InNextStr As String
If InNowStr = "" Then cnt = cnt + 1 Rez(cnt, 1) = OutNowStr Else k = Len(InNowStr) For i = 1 To k OutNextStr = OutNowStr & Mid(InNowStr, i, 1) InNextStr = Mid(InNowStr, 1, i - 1) & Mid(InNowStr, i + 1, k - i) PermSmpl OutNextStr, InNextStr Next i End If End Sub
[/vba]
"Понял, это из-за нехватки ячеек." Ячеек там более 1 млн (и это только в одном столбце!). Просто Integer замените на Long Вот с массивом, который выводится на лист
[vba]
Код
Option Explicit Dim cnt As Long Dim Rez() As String
Sub Comb() Dim InputStr As String, OutputStr As String
cnt = 0: OutputStr = "" Sheets("Лист1").Columns(1).ClearContents InputStr = Sheets("Лист1").Range("C2").Value ReDim Rez(1 To WorksheetFunction.Fact(Len(InputStr)), 1 To 1)
PermSmpl OutputStr, InputStr Range("A1").Resize(cnt).Value = Rez() Erase Rez End Sub
Sub PermSmpl(OutNowStr As String, InNowStr As String) Dim k As Long 'length of the input letters Dim i As Long Dim OutNextStr As String, InNextStr As String
If InNowStr = "" Then cnt = cnt + 1 Rez(cnt, 1) = OutNowStr Else k = Len(InNowStr) For i = 1 To k OutNextStr = OutNowStr & Mid(InNowStr, i, 1) InNextStr = Mid(InNowStr, 1, i - 1) & Mid(InNowStr, i + 1, k - i) PermSmpl OutNextStr, InNextStr Next i End If End Sub
Есть несколько вопросов: 1. Какова конечная цель? 2. Нужны размещения или достаточно только перестановок? Если нужны размещения, то обязательно ли их генерировать в лексикографическом порядке? Можно использовать двойной подход: генерируем сочетания и для каждого сочетания генерируем перестановки, но не получится лексикографического порядка 3. обязательно ли работать со строковыми переменными или можно работать с числами в массиве?
Есть несколько вопросов: 1. Какова конечная цель? 2. Нужны размещения или достаточно только перестановок? Если нужны размещения, то обязательно ли их генерировать в лексикографическом порядке? Можно использовать двойной подход: генерируем сочетания и для каждого сочетания генерируем перестановки, но не получится лексикографического порядка 3. обязательно ли работать со строковыми переменными или можно работать с числами в массиве?MCH
1. Какова конечная цель? 2. Нужны размещения или достаточно только перестановок? Если нужны размещения, то обязательно ли их генерировать в лексикографическом порядке? Можно использовать двойной подход: генерируем сочетания и для каждого сочетания генерируем перестановки, но не получится лексикографического порядка 3. обязательно ли работать со строковыми переменными или можно работать с числами в массиве?
1.Сделать функцию, генерирующую комбинации из слагаемых выражений:
т.е. чтобы не записывать все варианты в формуле а подставить функцию со ссылкой на ячейки с числами (элементы перестановок). В формуле F6*(D8/(D4-D6))*(D5/(D4-D6-D8)) - это одна (из 72) комбинация состоящая из 3х элементов (между элементами знак умножения). Вычитаемое второго элемента зависит от первого элемента (D6), а вычитаемые 3го элемента зависят от 1 и 2 элементов (D6 и D8). 2.Достаточно перестановок и лексикографический порядок не обязателен. 3.Как написал выше функция нужна для работы с числами.
1. Какова конечная цель? 2. Нужны размещения или достаточно только перестановок? Если нужны размещения, то обязательно ли их генерировать в лексикографическом порядке? Можно использовать двойной подход: генерируем сочетания и для каждого сочетания генерируем перестановки, но не получится лексикографического порядка 3. обязательно ли работать со строковыми переменными или можно работать с числами в массиве?
1.Сделать функцию, генерирующую комбинации из слагаемых выражений:
т.е. чтобы не записывать все варианты в формуле а подставить функцию со ссылкой на ячейки с числами (элементы перестановок). В формуле F6*(D8/(D4-D6))*(D5/(D4-D6-D8)) - это одна (из 72) комбинация состоящая из 3х элементов (между элементами знак умножения). Вычитаемое второго элемента зависит от первого элемента (D6), а вычитаемые 3го элемента зависят от 1 и 2 элементов (D6 и D8). 2.Достаточно перестановок и лексикографический порядок не обязателен. 3.Как написал выше функция нужна для работы с числами.Mexo
Сообщение отредактировал Mexo - Среда, 06.12.2017, 02:17
Или все таки нужны размещения (не перестановки), всех запутал и себя, простите! И еще нужно чтобы один элемент находился на последней позиции как в этой формуле D5.
Или все таки нужны размещения (не перестановки), всех запутал и себя, простите! И еще нужно чтобы один элемент находился на последней позиции как в этой формуле D5.Mexo
Сообщение отредактировал Mexo - Среда, 06.12.2017, 14:54
см. сообщение № 9, там два варианта реализации. Сделаны функции по генерации следующего сочетания, следующей перестановки и следующего размещения из исходного массива Можно не генерировать весь массив для выгрузки на лист, а последовательно перебирать все размещения (или перестановки или сочетания). Реализовано без рекурсий, поэтому не нужно использовать глобальные переменные.
см. сообщение № 9, там два варианта реализации. Сделаны функции по генерации следующего сочетания, следующей перестановки и следующего размещения из исходного массива Можно не генерировать весь массив для выгрузки на лист, а последовательно перебирать все размещения (или перестановки или сочетания). Реализовано без рекурсий, поэтому не нужно использовать глобальные переменные.MCH
Спасибо! Как теперь мне сконструировать код в примере (модуль2) на "Лист2" чтобы вместо цифр были значения ячеек из диапазона "elements"? И как еще можно добавить параметр "элемент на последней позиции"? Например в ячейку "last pos" ввожу цифру, которая соответствует порядковому номеру ячейки из диапазона "elements" допустим 3. И сгенерируются только те комбинации, где значение из ячейки L12 будет на последней позиции.
Спасибо! Как теперь мне сконструировать код в примере (модуль2) на "Лист2" чтобы вместо цифр были значения ячеек из диапазона "elements"? И как еще можно добавить параметр "элемент на последней позиции"? Например в ячейку "last pos" ввожу цифру, которая соответствует порядковому номеру ячейки из диапазона "elements" допустим 3. И сгенерируются только те комбинации, где значение из ячейки L12 будет на последней позиции.Mexo