|
Алгоритм получения комбинации строк | ☑ | ||
---|---|---|---|---|
0
Balabass
15.09.17
✎
07:37
|
Коллеги, извините, но нид хелп. Не соображу как оптимально построить алгоритм сложения строк.
Исходные данные: Массив[3] 1 = а 2 = б 3 = с Надо перебрать все варианты возможных комбинаций длинною от 1 до 3х знаков и получить в результате таблицу а б в аа аб ав ба бб бв ва вб вв ааа ааб и т.д. Буду признателен за функцию комбинаторики. Ключевая особенность - не получать на ВОЗВРАТ таблицу со всеми вариантами, а получать СТРОКУ, следующую по номеру комбинации. |
|||
1
1dvd
15.09.17
✎
07:47
|
как-то так
ДлинаМассива = 3; Мас = Новый Массив(ДлинаМассива); Мас[0] = "а"; Мас[1] = "б"; Мас[2] = "с"; Номер = 20; Н1 = Номер % ДлинаМассива; Н2 = Цел(Номер / ДлинаМассива) % ДлинаМассива; Н3 = Цел(Цел(Номер / ДлинаМассива) / ДлинаМассива); Результат = Мас[Н1] + Мас[Н2] + Мас[Н3]; |
|||
2
1dvd
15.09.17
✎
07:50
|
хотя, если тебе нужны комбинации из 1 и 2 элементов, то надо доработать
|
|||
3
Йохохо
15.09.17
✎
07:59
|
(2) перевести в троичную систему счисления?)
|
|||
4
Zmich
15.09.17
✎
08:18
|
(0).
Функция ПолучитьСтрокуПоНомеру(Номер) Массив = Новый Массив(3); Массив[0] = "а"; Массив[1] = "б"; Массив[2] = "в"; Если (Номер >= 1) И (Номер <=3) Тогда Стр = Массив[(Номер-1)%3]; ИначеЕсли (Номер >=4) И (Номер <=12) Тогда Стр = Массив[Цел((Номер - 4)/3)] + Массив[(Номер-1)%3]; ИначеЕсли (Номер >=13) И (Номер <= 39) Тогда Стр = Массив[Цел((Номер - 13)/9)] + Массив[(Цел((Номер - 1)/3) - 1)%3] + Массив[(Номер-1)%3]; Иначе Стр = "Номер за пределами возможных значений!"; КонецЕсли; Возврат Стр; КонецФункции Конечно, можно доработать для произвольного числа символов, но лень. |
|||
5
v77
15.09.17
✎
08:30
|
||||
6
Ненавижу 1С
гуру
15.09.17
✎
09:03
|
||||
7
Ёпрст
15.09.17
✎
09:12
|
(0)
пихай в запрос и кросс джоин |
|||
8
Широкий
15.09.17
✎
09:13
|
Детский сад. В таблицу и полное соединение
|
|||
9
Широкий
15.09.17
✎
09:17
|
ВЫБРАТЬ
"a" КАК Буква ПОМЕСТИТЬ Алфавит ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ "b" ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ "c" ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ "" ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Алфавит1.Буква + Алфавит2.Буква + Алфавит3.Буква КАК Слово ИЗ Алфавит КАК Алфавит1, Алфавит КАК Алфавит2, Алфавит КАК Алфавит3 УПОРЯДОЧИТЬ ПО Алфавит1.Буква, Алфавит2.Буква, Алфавит3.Буква |
|||
10
Ненавижу 1С
гуру
15.09.17
✎
09:20
|
(9)это не полное соединение, а внутреннее
|
|||
11
Ненавижу 1С
гуру
15.09.17
✎
09:23
|
+(9) немного улучшу:
ВЫБРАТЬ РАЗЛИЧНЫЕ Алфавит1.Буква + Алфавит2.Буква + Алфавит3.Буква КАК Слово ИЗ Алфавит КАК Алфавит1, Алфавит КАК Алфавит2, Алфавит КАК Алфавит3 ГДЕ Алфавит1.Буква + Алфавит2.Буква + Алфавит3.Буква<>"" УПОРЯДОЧИТЬ ПО Алфавит1.Буква + Алфавит2.Буква + Алфавит3.Буква |
|||
12
Ёпрст
15.09.17
✎
09:25
|
(10) это cross join
|
|||
13
Йохохо
15.09.17
✎
09:25
|
в (0) "Ключевая особенность - не получать на ВОЗВРАТ таблицу со всеми вариантами, а получать СТРОКУ, следующую по номеру комбинации."
|
|||
14
Широкий
15.09.17
✎
09:26
|
(10) Согласен, внутреннее.
(11) Доведу до идеала //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ РАЗЛИЧНЫЕ Результат.Слово КАК Слово ИЗ (ВЫБРАТЬ Алфавит1.Буква + Алфавит2.Буква + Алфавит3.Буква КАК Слово ИЗ Алфавит КАК Алфавит1, Алфавит КАК Алфавит2, Алфавит КАК Алфавит3) КАК Результат ГДЕ Результат.Слово <> "" УПОРЯДОЧИТЬ ПО Слово |
|||
15
Ёпрст
15.09.17
✎
09:27
|
(14) да не иннер это, а кросс.
|
|||
16
Ёпрст
15.09.17
✎
09:27
|
иннер будет, если условие наложить
|
|||
17
Вафель
15.09.17
✎
09:31
|
+1 к последнему элементу массива, если = 3 то +1 ко второму,а последний = 0.
Элементарный алгоритм |
|||
18
Широкий
15.09.17
✎
09:32
|
(15) В скуле - да. По понятиям 1с - это внутреннее соединение.
|
|||
19
Широкий
15.09.17
✎
09:38
|
Не поленился в профайлер слазить:
SELECT DISTINCT #V8TblAli1_Q_002_T_001._Q_001_F_000 AS _sf_1 FROM ( SELECT #T55cd2562e102435c8a0e2eb85a5a3fbf_Q_001_T_001._Q_000_F_000 + #T55cd2562e102435c8a0e2eb85a5a3fbf_Q_001_T_002._Q_000_F_000 + #T55cd2562e102435c8a0e2eb85a5a3fbf_Q_001_T_003._Q_000_F_000 AS _Q_001_F_000 FROM #tt2 #T55cd2562e102435c8a0e2eb85a5a3fbf_Q_001_T_001 WITH(NOLOCK) INNER JOIN #tt2 #T55cd2562e102435c8a0e2eb85a5a3fbf_Q_001_T_002 WITH(NOLOCK) ON 0 = 0 INNER JOIN #tt2 #T55cd2562e102435c8a0e2eb85a5a3fbf_Q_001_T_003 WITH(NOLOCK) ON 0 = 0 ) #V8TblAli1_Q_002_T_001 WHERE #V8TblAli1_Q_002_T_001._Q_001_F_000 <> CAST(@P1 AS NVARCHAR(1)) ORDER BY _sf_1 1с его в inner транслирует |
|||
20
Ёпрст
15.09.17
✎
09:42
|
(19) см. (16)
|
|||
21
Широкий
15.09.17
✎
09:45
|
(20) условия в 1с запросе нет, но в скуле все равно inner
|
|||
22
Михаил Козлов
15.09.17
✎
09:53
|
Почему не (3)?
Только нужно иметь в виду, что это будут 3-х символьные значения. Нужно к ним добавить 1 и 2-х символьные. Всего: 3+9+27 = 39 значений. |
|||
23
Йохохо
15.09.17
✎
09:56
|
(22) 2 это односимвольное значение, 4 двух, все хорошо
(20) в книжке селф джойн разворачивают как иннер |
|||
24
Zmich
15.09.17
✎
10:19
|
(14). В таком варианте возможно слово "a b", т.е. с пробелом посередине. Плюс слова "ab " и " ab" (с пробелом в начале и в конце) будут выбраны, как различные.
|
|||
25
Широкий
15.09.17
✎
10:23
|
(24) Там пустая строка, не пробел. Посмотри сам
|
|||
26
Zmich
15.09.17
✎
10:26
|
(25). А, ок тогда, всё верно.
|
|||
27
1dvd
15.09.17
✎
10:26
|
(25) один хрен будут повторяться
|
|||
28
Zmich
15.09.17
✎
10:47
|
(27). Повторяться не будут (ВЫБРАТЬ РАЗЛИЧНЫЕ).
(14). Думаю, что сортировка правильно работать не будет. Порядок в выборке, по-видимому, будет такой: а, аа, ааа, ааб, аав, аб, аба, абб и т.д., а не такой, как нужно автору. Как по номеру предполагается слово получать? |
|||
29
RS2017
15.09.17
✎
11:00
|
Запрос для данной задачи - бред. Он явно загнется при вводе например 99999999999. Правильная идея в (4), реализация правда слишком линейная)).
|
|||
30
Ненавижу 1С
гуру
15.09.17
✎
11:02
|
(15) йопта:
CROSS JOIN это INNER JOIN ON (1=1) |
|||
31
Ёпрст
15.09.17
✎
11:12
|
(30) я в курсе. Но правильно, называть вещи своими именами
|
|||
32
Филиал-msk
15.09.17
✎
11:13
|
Какая пятничная ветка...
Думаете, 1С при присвоении следующего буквенного номера/кода тоже джоины и декартовы произведения прокручивает? (: |
|||
33
Широкий
15.09.17
✎
11:36
|
(29) Молодой ты еще.
Я попробовал на 12 символах. Не загнулась. Отработала за 16 сек (с учетом вывода результата в табличную часть) |
|||
34
тарам пам пам
15.09.17
✎
12:01
|
эхх, погромисты....
бОльшая часть даже условие не дочитала (про то, что не нужно при вызове функции формировать полную таблицу) задача элементарная же. Цифры слева - индексы исходного массива, цифры справа - число, переданное в функцию: 0 = а = 0 1 = б = 1 2 = в = 2 00 = аа = 3 01 = аб = 4 02 = ав = 5 10 = ба = 6 11 = бб = 7 12 = бв = 8 20 = ва = 9 21 = вб = 10 22 = вв = 11 000 = ааа = 12 001 = ааб = 13 002 = аав = 14 010 = аба = 15 011 = абб = 16 012 = абв = 17 020 = ава = 18 021 = авб = 19 022 = авв = 20 100 = баа = 21 101 = баб = 22 102 = бав = 23 110 = бба = 24 111 = ббб = 25 112 = ббв = 26 120 = бва = 27 121 = бвб = 28 122 = бвв = 29 200 = ваа = 30 201 = ваб = 31 202 = вав = 32 210 = вба = 33 211 = вбб = 34 212 = вбв = 35 220 = вва = 36 221 = ввб = 37 222 = ввв = 38 если внимательно посмотреть, то индексы массива можно получить следующим образом - делим исходное число на 3, остаток записываем, вычитаем из результата 1, делим результат на 3, записываем остаток и т. д. Примеры: 7 7 / 3 = 2, остаток 1 (2-1) / 3 = 0, остаток 1 20 20 / 3 = 6, остаток 2 (6-1) / 3 = 1, остаток 2 (1-1) / 3 = 0, остаток 0 34 34 / 3 = 11, остаток 1 (11-1) / 3 = 3, остаток 1 (3-1) / 3 = 0, остаток 2 15: 15 / 3 = 5, остаток 0 (5-1) / 3 = 1, остаток 1 (1-1) / 3 = 0, остаток 0, 30: 30 / 3 = 10, остаток 0 9 / 3 = 3, остаток 0 2 / 3 = 0, остаток 2 |
|||
35
Zmich
15.09.17
✎
12:13
|
(34). В (4) всё это и сделано, идея еще в (1) была.
|
|||
36
RS2017
15.09.17
✎
12:21
|
(33) 3^12 = 531441 как бы в на 6-7 порядков меньше чем 99999999999. Или ты считаешь, что 16*10^6 секунд (предполагаем, что время будет расти линейно) это приемлемое время? Особенно при наличии решения менее чем за 0.001 сек (это на 1С).
|
|||
37
тарам пам пам
15.09.17
✎
13:37
|
(35) в (4) жестко прописаны все границы. Для каждой новой длины массива писать новый алгоритм? В (1) нечто более близкое, но там не ясно, как алгоритм распространить для произвольной длины массива.
|
|||
38
RS2017
15.09.17
✎
13:49
|
(37) всё там ясно: сначала определяем число разрядов(последовательно вычитая 3^N), потом остаток выводим в троичной системе с лидирующими нулями до нужного числа разрядов.
Естественно будет несколько циклов, а не как в (4) |
|||
39
Йохохо
15.09.17
✎
14:29
|
(38) Используй рекурсию Люк!
|
|||
40
Вафель
15.09.17
✎
14:31
|
вообще по идее нужна функция, которая на входе берез массив [1, 2, 3] на выходе получать массив [1, 3, 1]
|
|||
41
RS2017
15.09.17
✎
14:40
|
(39) можно и без рекурсии, можно и с рекурсией если очень хочется. Здесь она абсолютным злом не будет.
(40) ничего пе понятно. На входе число [4], на выходе строка "aa" |
|||
42
Вафель
15.09.17
✎
14:42
|
(41) Зачем число? лишний раз только в другую систему переводить
|
|||
43
Вафель
15.09.17
✎
14:42
|
тут счетчик не число, а массив
|
|||
44
RS2017
15.09.17
✎
14:44
|
(42) "Зачем число?" это условие задачи, прочитай последнее предложение (0)
Я тебя не очень понимаю, расшифруй пример в (40) |
|||
45
Вафель
15.09.17
✎
14:45
|
(44) Я смотрю на шаг дальше )))
|
|||
46
Йохохо
15.09.17
✎
14:53
|
(4) а красивая идея, тлько код будет коряво смотреться
|
|||
47
Йохохо
15.09.17
✎
14:58
|
вообще олскульно через код символа, инкремент и обработку переполнения разряда, лепота
|
|||
48
RS2017
15.09.17
✎
15:05
|
(45) Так поясни, я так далеко не вижу). Хотя я вижу решение от начала и до конца.
(46) там сейчас коряво. Что там будет коряво с двумя циклами, не представляю. На вкус и цвет... |
|||
49
RS2017
15.09.17
✎
15:05
|
(47) Это как "инкремент", перебирать подряд?
|
|||
50
Вафель
15.09.17
✎
15:10
|
(48) Типо такого
Счетчик = [1, 1, 1]; Пока Счетчик <= [3, 3, 3] Цикл Сообщить(СобратьСтроку(Счетчик)); Следующий(Счетчик); КонецЦикла; |
|||
51
Balabass
15.09.17
✎
15:18
|
Участникам беседы респект и уважение.
В (0) пример достаточно простой - для понимания задачи. Я увидел варианты решения, пойду покапаю. |
|||
52
RS2017
15.09.17
✎
15:19
|
(50) ты опять перебор всех значений для 3 разрядов? Для 3 разрядов можно ручками в массив записать. В (0) задача по произвольному индексу получить "типа троичное" представление.
|
|||
53
Вафель
15.09.17
✎
15:25
|
Нужно у ТС спросить.
Доступ по индексу нужен или построчное формирование значений. |
|||
54
Вафель
15.09.17
✎
15:25
|
Я вангую, что, все-таки, построчное формирование
|
|||
55
RS2017
15.09.17
✎
15:35
|
(54) (53) прочитай последнее предложение (0)
|
|||
56
Balabass
15.09.17
✎
15:40
|
(53) Построчное.
|
|||
57
Вафель
15.09.17
✎
15:44
|
(55) Какчай уровень телепатии, джуниор )))
|
|||
58
RS2017
15.09.17
✎
15:45
|
(56) т.е. тебе всё-таки надо "получать на ВОЗВРАТ таблицу"?
|
|||
59
Вафель
15.09.17
✎
15:46
|
(58) Всю заранее не нужно. А ля перебор паролей. где-то там посередине есть нужная комбинация
|
|||
60
RS2017
15.09.17
✎
15:50
|
(57) )))красавец, из серии "послушай женщину и сделай наоборот"
(59) т.е. никакого номера комбинации не существует? тогда действительно проще перебирать запросом. |
|||
61
Вафель
15.09.17
✎
16:16
|
Накидал алгоритм перебора
https://gist.github.com/a-sitnikov/aed4a8360622e80890e6750756b785bf |
|||
62
Йохохо
15.09.17
✎
22:18
|
непонятен такой уровень решения, Ненавижу 1с даже в сових темах предлагает не оптимальные решения
Семнадцать из трёх тысяч |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |