Имя: Пароль:
1C
1С v8
Всевозможные комбинации цифр
0 FOFA
 
30.11.13
22:55
Есть цифры, например 1,2,3,4

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

Примерно так:
1    2    3    4
1    2    4    3
1    3    2    4
1    3    4    2
2    1    3    4
2    3    1    4
2    4    1    3

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

Спасибо

Пол дня думаю и рыскаю по интернету и не могу найти
1 Волшебник
 
модератор
30.11.13
22:58
Преобразуй в двоичную систему
2 dervishsy
 
30.11.13
22:59
4 вложенных цикла
3 FOFA
 
30.11.13
23:01
Не, циклами нельзя...
Цифер бедет не 4..Это как пример
4 dervishsy
 
30.11.13
23:02
Ну тогда вступает страшная рекурсия
5 RomanYS
 
30.11.13
23:04
6 FOFA
 
30.11.13
23:11
(5) Спасибо
Попробую реализовать
7 GANR
 
30.11.13
23:36
(2) Лобовое решение - не самый хороший вариант при больших объемах данных.
8 salih020292
 
30.11.13
23:39
Комбинаторика, не ?
9 RomanYS
 
01.12.13
00:27
Рекурсивно:
Перем Н, Исх;

Процедура Перебор(Тек)
    Если СтрДлина(Тек) = Н Тогда
        Сообщить(Тек);
        возврат;
    КонецЕсли;
    Для инд = 1 По Н Цикл
        Симв = Сред(Исх, инд, 1);
        Если Найти(Тек, Симв) = 0 Тогда
            Перебор(Тек+Симв)
        КонецЕсли;
    КонецЦикла;

КонецПроцедуры

Процедура КнопкаВыполнитьНажатие(Кнопка)
    Н = 7;
    Исх = "0123456789";
    Перебор("");
КонецПроцедуры


без рекурсии не осилил
10 xenos
 
01.12.13
00:48
(9) > Найти(Тек, Симв)

Не самый лучший вариант, лучше массив использовать.
11 sda553
 
01.12.13
00:54
Загоняем в таблицу НашаТаб эти 4 цифры и потом просто:

выбрать а1.цифра, а2.цифра, а3.цифра, а4.цифра
из
НашаТаб как а1, НашаТаб как а2, НашаТаб как а3, НашаТаб как а4
12 crazy_killer
 
01.12.13
00:57
(11) мда...
13 crazy_killer
 
01.12.13
00:58
а то, что значения будут повторяться, что нарушает условие задачи, ну это ничего...
14 xenos
 
01.12.13
02:16
Процедура КнопкаВыполнитьНажатие(Кнопка)
    // Вставить содержимое обработчика.
    КолЦифр=4;
    
    Комбинация=новый Массив(КолЦифр+1);
    ИспользованыЦифры=новый Массив(КолЦифр+1);
    
    Для ном=0 по КолЦифр Цикл
        Комбинация[ном]=0;
        ИспользованыЦифры[ном]=ложь;
    КонецЦикла;
    
    ПодобраноЦифр=1;
    
    Выполнять=Истина;
    Пока Выполнять Цикл
        НайденнаяЦифра=0;
        Счетчик=Комбинация[ПодобраноЦифр]+1;
        Пока Счетчик<=КолЦифр Цикл
            Если  ИспользованыЦифры[Счетчик]= ложь ТОгда
                НайденнаяЦифра=Счетчик;
                ИспользованыЦифры[Счетчик]= Истина;
                Прервать;
            КонецЕсли;    
            Счетчик=Счетчик+1;
        КонецЦикла;
        ИспользованыЦифры[Комбинация[ПодобраноЦифр]]= Ложь;
        
        Если НайденнаяЦифра<>0 ТОгда
            Комбинация[ПодобраноЦифр]=НайденнаяЦифра;
            Если ПодобраноЦифр=КолЦифр Тогда
                стрКомбинация="";
                
                Для ном=1 по КолЦифр Цикл
                    стрКомбинация=стрКомбинация+Строка(Комбинация[ном]);
                КонецЦикла;
                Сообщить(стрКомбинация);
                
                
                ИспользованыЦифры[Комбинация[ПодобраноЦифр]]= Ложь;
                
                Комбинация[ПодобраноЦифр]=0;
                ПодобраноЦифр=ПодобраноЦифр-1;
            Иначе
                ПодобраноЦифр=ПодобраноЦифр+1;
            КонецЕсли;
        Иначе
            Комбинация[ПодобраноЦифр]=0;
            ПодобраноЦифр=ПодобраноЦифр-1;
        КонецЕсли;
        
        Если  ПодобраноЦифр=0 Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла
КонецПроцедуры
15 wertyu
 
01.12.13
02:25
(0) 4! простейшая из функций Эйлера-Римана
16 xenos
 
01.12.13
02:32
немного упростил

Процедура КнопкаВыполнитьНажатие(Кнопка)
    КолЦифр=4;
    
    Комбинация=новый Массив(КолЦифр+1);
    ИспользованыЦифры=новый Массив(КолЦифр+1);
    
    Для ном=0 по КолЦифр Цикл
        Комбинация[ном]=0;
        ИспользованыЦифры[ном]=ложь;
    КонецЦикла;
    
    ПодобраноЦифр=1;
    
    Пока Истина Цикл
        ИспользованыЦифры[Комбинация[ПодобраноЦифр]]= Ложь;
        Счетчик=Комбинация[ПодобраноЦифр]+1;
        Пока Счетчик<=КолЦифр Цикл
            Если  ИспользованыЦифры[Счетчик]= ложь ТОгда
                Комбинация[ПодобраноЦифр]=Счетчик;
                ИспользованыЦифры[Счетчик]= Истина;
                
                Если ПодобраноЦифр=КолЦифр Тогда
                    стрКомбинация="";
                    Для ном=1 по КолЦифр Цикл
                        стрКомбинация=стрКомбинация+Строка(Комбинация[ном]);
                    КонецЦикла;
                    Сообщить(стрКомбинация);
                    
                    ИспользованыЦифры[Комбинация[ПодобраноЦифр]]= Ложь;
                    Комбинация[ПодобраноЦифр]=0;
                    ПодобраноЦифр=ПодобраноЦифр-1;
                Иначе
                    ПодобраноЦифр=ПодобраноЦифр+1;
                КонецЕсли;
                
                Прервать;
            КонецЕсли;    
            Счетчик=Счетчик+1;
        КонецЦикла;
        
        Если Счетчик>КолЦифр Тогда
            Комбинация[ПодобраноЦифр]=0;
            ПодобраноЦифр=ПодобраноЦифр-1;
        КонецЕсли;
        
        Если  ПодобраноЦифр=0 Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла
КонецПроцедуры
17 FOFA
 
01.12.13
15:26
Все бы хорошо, но при количестве цифр больше 10, алгоритм начинает работать больше часа(
18 exwill
 
01.12.13
15:47
(0) Поищи алгоритм генерации перестановок.
19 FOFA
 
01.12.13
16:16
procedure Swap(a,b)
    Перем c;
    c=a;
    a=b;
    b=c;
Конецпроцедуры


procedure Generate(k)
    var i,j;
    if k=N then
        Врем = "";
        for i=1 to N do
            Врем = Врем + X[i];
        КонецЦикла;
        //Сообщить(Врем);
    else
        for j=k+1 to N do
            Swap(X[k+1],X[j]);
            Generate(k+1);
            Swap(X[k+1],X[j])
        КонецЦикла;
    КонецЕслИ;
КонецПроцедуры


Процедура КоманднаяПанель4Тест2Основний(Кнопка)
    N = 10;
    Сообщить(ТекущаяДАта());
    X = Новый Массив(N+1);
    for i=1 to N do X[i]=i;
    КонецЦикла;
    Generate(0);
    Сообщить(ТекущаяДАта());
    Сообщить("Ок");
КонецПроцедуры


Вот и алгоритм

Но есть новое НО
Большущее

Данный фрагмент на Паскале выполняется 2 секунды для 10 цифр, в 1с он выполняется уже 10 минут(

Что делать не знаю(
20 xenos
 
01.12.13
16:57
(19) > Данный фрагмент на Паскале выполняется 2 секунды для 10 цифр, в 1с он выполняется уже 10 минут(

96% времени используется для операции "Сообщить".
21 FOFA
 
01.12.13
17:12
(19)..Я убрал сообщить..
Как раз сам сравнивал
22 Lama12
 
01.12.13
22:24
(0) Сколько будет цифр?
Один цикл в системе счисления с базой в количество цифр.