Имя: Пароль:
1C
 
Подскажите как получить все возможные перестановки?
0 RomaH
 
naïve
11.04.13
14:31
На входе имеем массив значений

на выходе надо получить массив массивов со всеми возможными перестановками элементов исходного

например:
123
132
213
231
312
321

для 4 элементов уже будет 24 перестановки
1 Trainee
 
11.04.13
14:33
)) Загнать элементы в массив и 2 циклами прогуляться. Как во всех "hello world!"
2 Nina2005
 
11.04.13
14:35
запросом полное объединение сделать можно
3 RomaH
 
naïve
11.04.13
14:43
(2) вариант
(1) а поподробнее?
Для а = 1 по Н цикл

Для б = 1 по Н Цикл

так количество циклов будет меньше чем надо
4 acsent
 
11.04.13
14:45
5 В тылу врага
 
11.04.13
14:47
(0) логично, для N элементов будет N! перестановок, а зачем это в 1С?
6 Slon747
 
11.04.13
14:47
(0) Почитать теорию вероятностей и мат. статистику.
Там формула с факториалом.
7 Trainee
 
11.04.13
15:04
(3) Почему меньше?
1 2 3 (1)
1 2 3 (2)
1 2 3 (3)
Первый цикл по строке (1)
Второй цикл по строке (2)
...
N-цикл по строке (n)(зависимость от размерности массива)

Можно, наверное, и с факториалом, просто функция рекурсивная будет.
8 RomaH
 
naïve
11.04.13
22:23
(4) спасибо
(5) для поиска, например контрагентов
надо найти наименования содержащие СЛОВА содержащие заданный текст в любой последовательности

костромская медицинская страховая организация

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

в общем-то с этой задачей практически справляется полнотекстовый поиск, но не всегда
при большом количестве совпадений - слишком долго
а на коротких фразах вообще не работает
9 HeroShima
 
11.04.13
23:02
учите правильные инструменты:
itertools.permutations('123')
-пригодится
10 Злопчинский
 
11.04.13
23:06
(8) а для чего здесь вообще перестановки нужны..? насколько ясебе представляю - запросом решается на вхождение ...?
11 Jonny_Khomich
 
12.04.13
06:34
Такой поиск явно не быстрый. (0)
12 RomaH
 
naïve
12.04.13
06:52
(10) читай (8) внимательно
13 RomaH
 
naïve
12.04.13
06:58
(11) вполне устраивает
сейчас справочник 10 000 элементов - поиск по двум полям Наименование и полное наименование - неудобств не возникает
14 RomaH
 
naïve
12.04.13
07:26
(2) а поподробнее?
текст запроса похоже тоже придется динамически формировать
с кучей условий
15 1Сергей
 
12.04.13
07:41
Я б рекурсией сделал
16 AnKa4
 
12.04.13
07:50
Рекурсия:

КоличествоУровней = 3;
КоличествоЭлементовВМассиве = 8;
ВывестиВариантыПерестановок("", 1, КоличествоУровней, КоличествоЭлементовВМассиве)

Процедура ВывестиВариантыПерестановок(ВариантПерестановки, Уровень, КоличествоУровней, КоличествоЭлементовВМассиве)
   Если Уровень > КоличествоУровней Тогда
       Сообщить(ВариантПерестановки);
       Возврат;
   КонецЕсли;
   Для Инд = 1 По КоличествоЭлементовВМассиве Цикл
       ВывестиВариантыПерестановок(ВариантПерестановки + Строка(Инд), Уровень + 1, КоличествоУровней, КоличествоЭлементовВМассиве);    
   КонецЦикла;
КонецПроцедуры
17 RomaH
 
naïve
12.04.13
08:01
получается что-то типа такого:

ВЫБРАТЬ
   1 КАК Поле1
ПОМЕСТИТЬ втИсходник

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   2

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   3

ОБЪЕДИНИТЬ

ВЫБРАТЬ
   4
ОБЪЕДИНИТЬ

ВЫБРАТЬ
   5
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   втИсходник1.Поле1,
   втИсходник2.Поле1 КАК Поле11,
   втИсходник3.Поле1 КАК Поле12,
   втИсходник4.Поле1 КАК Поле13,
   втИсходник5.Поле1 КАК Поле14
ИЗ
   втИсходник КАК втИсходник1,
   втИсходник КАК втИсходник2,
   втИсходник КАК втИсходник3,
   втИсходник КАК втИсходник4,
   втИсходник КАК втИсходник5
ГДЕ
   втИсходник1.Поле1 <> втИсходник2.Поле1
   И втИсходник1.Поле1 <> втИсходник3.Поле1
   И втИсходник1.Поле1 <> втИсходник4.Поле1
   И втИсходник1.Поле1 <> втИсходник5.Поле1
   И втИсходник2.Поле1 <> втИсходник1.Поле1
   И втИсходник2.Поле1 <> втИсходник3.Поле1
   И втИсходник2.Поле1 <> втИсходник4.Поле1
   И втИсходник2.Поле1 <> втИсходник5.Поле1
   И втИсходник3.Поле1 <> втИсходник1.Поле1
   И втИсходник3.Поле1 <> втИсходник2.Поле1
   И втИсходник3.Поле1 <> втИсходник4.Поле1
   И втИсходник3.Поле1 <> втИсходник5.Поле1
   И втИсходник4.Поле1 <> втИсходник1.Поле1
   И втИсходник4.Поле1 <> втИсходник2.Поле1
   И втИсходник4.Поле1 <> втИсходник3.Поле1
   И втИсходник4.Поле1 <> втИсходник5.Поле1
18 RomaH
 
naïve
12.04.13
08:05
(15) вопрос - как?
(16) - не то
как минимум на первом проходе получим не верный ответ
19 organizm
 
12.04.13
08:05
а по ИНН/КПП найти дублей не судьба?
20 organizm
 
12.04.13
08:06
(19) останется только с иностранцами разобраться
21 organizm
 
12.04.13
08:09
делать по неточным условиям такие серьёзные вещи не корректно
22 1Сергей
 
12.04.13
08:12
23 AnKa4
 
12.04.13
08:13
(18) Пробовал запустить? Это рабочий код.
24 HeroShima
 
12.04.13
08:14
(12) Прог, не могущий перебрать все варианты, не может правильно оценить более сложные алгоритмы.
25 AnKa4
 
12.04.13
08:17
(23) + Это просто перебор всех вариантов. Вместо Сообщить() можешь проверять на соответствие твоим условиям и записывать их в массив.
26 RomaH
 
naïve
12.04.13
08:35
(25) спасибо
27 RomaH
 
naïve
12.04.13
08:36
(19) а при чем тут ИНН?
задача найти контрагента со слов пациента
28 RomaH
 
naïve
12.04.13
09:56
итог:

Функция ПолучитьИндексыПерестановкиПоДлинеМассива(ДлинаМассива) Экспорт
   
   ТекстЗапроса1 =
   "ВЫБРАТЬ
   |    1 КАК Поле1
   |ПОМЕСТИТЬ втИсходник";

   ТекстЗапроса2 =
   "
   |;
   |
   |ВЫБРАТЬ
   |    втИсходник1.Поле1";
   
   ТекстЗапроса3 =
   "
   |ИЗ
   |    втИсходник КАК втИсходник1";
   
   ТекстЗапроса4 =
   "
   |ГДЕ Истина";

   Для К = 2 По ДлинаМассива Цикл
       
       ИП = Формат(К,"ЧГ=0");
       ИПП = Формат(К-1,"ЧГ=0");
       
       ТекстЗапроса1 = ТекстЗапроса1 +
       "
       |ОБЪЕДИНИТЬ
       |ВЫБРАТЬ
       |    " + ИП;    
       
       ТекстЗапроса2 = ТекстЗапроса2 +
       "," +
       "
       |втИсходник" + ИП + ".Поле1 КАК Поле" + ИП;
       
       ТекстЗапроса3 = ТекстЗапроса3 +  "," +
       "
       |втИсходник КАК втИсходник" + ИП;
       
       Для О = 1 По ДлинаМассива Цикл
           
           Если К-1 = О Тогда
               Продолжить;
           КонецЕсли;
           
           ИП = Формат(О,"ЧГ=0");
           
           ТекстЗапроса4 = ТекстЗапроса4 + "
           |    И втИсходник" + ИПП + ".Поле1 <> втИсходник" + ИП + ".Поле1";
           
       КонецЦикла;
       
   КонецЦикла;
   
   ТекстЗапроса = ТекстЗапроса1 + ТекстЗапроса2 + ТекстЗапроса3  + ТекстЗапроса4;
   
   Запрос = Новый Запрос;
   
   Запрос.Текст = ТекстЗапроса;
   
   Выборка = Запрос.Выполнить().Выбрать();
   
   МассивПерестановок = Новый Массив;
   Пока Выборка.Следующий() Цикл
       
       МассивИндексов = Новый Массив;
       
       Для К = 1 По ДлинаМассива Цикл
           МассивИндексов.Добавить(Выборка[К-1]);
       КонецЦикла;
       
       МассивПерестановок.Добавить(МассивИндексов);
       
   КонецЦикла;
   
   Возврат МассивПерестановок;
   
КонецФункции
29 Торин
 
12.04.13
10:01
или так:


Функция Перестановки(МассивДляПерестановки, СколькоПереставлять, итоговыйМассив)
   
   Если СколькоПереставлять=1 Тогда
       времМассив = МассивДляПерестановки.скопировать();
       итоговыйМассив.добавить(времМассив);
       возврат Истина;
   Иначе
       Для сч = 0 по СколькоПереставлять-1 Цикл
           Замена(МассивДляПерестановки[сч],МассивДляПерестановки[СколькоПереставлять - 1]); //меняем последний элемент с каждым, в том числе и с самим собой.
           Перестановки(МассивДляПерестановки,СколькоПереставлять - 1, итоговыйМассив); //запускаем функцию, для n-1 элементов
           Замена(МассивДляПерестановки[сч],МассивДляПерестановки[СколькоПереставлять - 1]); //Возвращаем массив в прежнее состояние для следующего обмена элементов
       КонецЦикла;
   КонецЕсли;
   
КонецФункции


Функция Замена(ПервоеСлово, ВтороеСлово)

   Врем         = ПервоеСлово.значение;
   ПервоеСлово.значение  = ВтороеСлово.значение;
   ВтороеСлово.значение  = Врем;
   
   возврат Истина;
   
КонецФункции
30 RomaH
 
naïve
12.04.13
10:47
СколькоПереставлять - это что?
31 organizm
 
12.04.13
12:29
(27) вполне может оказаться совпадающее название 2-х контрагентов, но они могут быть из разных регионов.
Ну найдешь ты по наименованю, точно совпавшего, а он вместо Москвы допустим в Магадане зарегестрирован. думаешь это нормально?