Как перебрать все варианты чего-либо

Навеяно темой с Мисты:
Имеем ряд чисел от одного до девяти, надо расставить знаки плюсы и минусы, чтобы получилось в сумме 20
1(+/-)2(+/-)3(+/-)4(+/-)5(+/-)6(+/-)7(+/-)8(+/-)9 = 20 (20 не получиться, это просто пример!!!)

Вот как можно автоматизировать пример, что бы получить все варианты расчета?

Я раньше занимался программированием на Ассемблере, так что для меня двоичная и шестнадцатиричная система счисления ближе десятичной.

1 = 1000, 2 = 0100, 3 = 1100, 4 = 0010 и т.д. из этого для примера возьмем 0 = Минус, 1 = Плюс

В выше указаном примере нам надо перебрать 8 различных подстановок +- (8 = 11111111B = 255D)

КоличествоВариантов = 8;
КоличествоВариантовРасчета = POW(2, КоличествоВариантов) — 1; //Расчитываем количество вариантов
Для ВариантРасчета = 0 По КоличествоВариантовРасчета Цикл       //Перебираем варианты
   
ЗначениеВариантаРасчета = ВариантРасчета;                              //Берем текущий вариант

    Пример = «»;                                                                                      //Текст примера
   
Для ПереборВарианта = 1 По КоличествоВариантов Цикл            //Перебираем расчет варианта
       
Вариант = ЗначениеВариантаРасчета%2;                                 // Получаем значение варианта

        //Здесь выполняем действие со значением варианта, в нашем примере знак «+» или «-«

        Знак = ?(Вариант = 1, «+», «-«);

        //Делаем текст примера

        Пример = Пример + ПереборВарианта  + Знак;

        //***

        ЗначениеВариантаРасчета = Цел(ЗначениеВариантаРасчета / 2); //Сдвигаем на следующее значение варианта
   
КонецЦикла;

    Пример = Пример + «9»;//т.к. последнее число не вошло в цикл просто добавим его.

    РасчетПримера = Вычислить(Пример);//Вычислим выражение

    Сообщить(Пример + » = » + РасчетПримера);

КонецЦикла;

 

По этому принципу расчета сделана моя обработка «Рюкзак».

26 Comments

  1. cool.vlad4

    Т.е. по сути это просто перебор всех возможных подстановок «+» и «-«? и неплохо бы, если есть упоминание на мисту, то хоть ссылку дать на исходную тему…

    Reply
  2. Ткачев

    А ссылку можно, не забанят ?

    http://forum.mista.ru/topic.php?id=576259

    Reply
  3. Alraune

    (2) Можно. Могли бы заодно и на свою обработку ссылку дать в тексте, раз ее упомянули.

    Reply
  4. Ткачев

    (3)А моем профиле разве не видно ссылок ?

    http://infostart.ru/public/88022/

    Reply
  5. Alraune

    (4) Видно. Но Вы переоцениваете любопытство читателей — в профиль искать полезет не каждый, а ткнуть в имеющуюся здесь же ссылку проще. Впрочем, дело Ваше

    Reply
  6. Ткачев

    (5)Да нее, я не спорю, зашугали просто мальчика банами за ссылки, пусть даже на текущий сайт.

    Reply
  7. Ткачев

    (1)»+» и «-» Это для примера, допустим есть таблица товаров и из нее нам надо выбрать набор товаров который не ниже суммы в 100 руб. и не выше суммы 200 руб.

    1) Отсеиваем товары у которых цена > 200 руб.

    2) Создаем Временную таблицу куда по условиям сложим товары сумма которых не превышает 200 руб.

    3) После 2-го цикла проверим на то что сумма у нас получилась > 100 руб. если «Истина» тогда добавим набор, если «Ложь» тогда очистим временную таблицу.

    Вариантов использования много.

    Reply
  8. cool.vlad4

    (7) по моему неудачный пример

    из нее нам надо выбрать набор товаров который не ниже суммы в 100 руб. и не выше суммы 200 руб.

    — раз создается временная таблица, то и решается запросом

    Да, я не спорю, полный перебор в любом случае где-нибудь используется.

    Reply
  9. Ткачев

    (8)Вот запросом было бы интересно посмотреть как это сделать, у меня не получилось, как я не пытался.

    Reply
  10. cool.vlad4

    (9) В смысле — набор товаров, а не товары, определенной суммой? Да, хрен, его знает, может можно, может нельзя, честно не знаю — не пытался. Да, вы поймите меня правильно ничего против вашей публикации не имею.

    Reply
  11. vkr

    (0) Вспомнить молодость… Написать подобную фигню на 10 разных языках — от Ассемблера до Перла… 🙂

    Reply
  12. evn-zorin

    Прям задача с чемпионата по программированию, автору спасибо за публикацию интересных алгоритмов!

    Reply
  13. tdr1225

    (0) а как будешь поступать, если надо выбирать не +/-, а, например, +/-/* или еще больше арифметических действий?

    Reply
  14. Ткачев

    (13)см.(7), запросом у меня не получается так сделать, может кто поможет ?

    Reply
  15. tdr1225

    (14) я не о том, ты не понял

    ты решал задачу: составить все слова длиной 8 символов из букв А и Б (0/1)

    а я предлагаю такую задачу: составить все слова длиной 8 символов из букв А, Б, В, Г.

    Reply
  16. tdr1225

    +

    или еще интересней, если и длина слова и количество букв — переменные (параметры)

    Reply
  17. Ткачев

    (15)(16)Если рассчитывать как в (0), получилось очень заковыристо, я сделал по другому.

    ВариантыБукв = «АБВГ»;

    КоличествоСимволов = СтрДлина(ВариантыБукв);

    КоличествоВариантов = 8;

    Массив = Новый Массив;

    Для Аа = 1 по КоличествоВариантов Цикл

    Массив.Добавить(1);

    КонецЦикла;

    Пока 1 Цикл

    СтрокаТекста = «»;

    Для Аб = 1 по КоличествоВариантов Цикл

    СтрокаТекста = СтрокаТекста + Сред(ВариантыБукв, Массив[Аб — 1], 1);

    КонецЦикла;

    Сообщить(СтрокаТекста);

    Фл = 0;

    Пока Массив[Фл] + 1 > КоличествоСимволов Цикл

    Массив[Фл] = 1;

    Фл = Фл + 1;

    Если Фл = КоличествоВариантов Тогда

    Возврат;

    КонецЕсли;

    КонецЦикла;

    Массив[Фл] = Массив[Фл] + 1;

    КонецЦикла;

    Reply
  18. see1c.ru
  19. tdr1225

    (18)

    не понял, а при чем здесь это?

    (17)

    на самом деле, это задача из комбинаторики о перестановках.

    надо юзать рекурсию

    Reply
  20. Ткачев

    (19)Примерчик можно ?

    Reply
  21. Арчибальд
    Язык дан человеку, чтобы скрывать свои мысли ©

    По тексту: Почему 2**8-1, а не 2**8?

    Далее: чем двоичная система отличается (кроме основания) от троичной, четверичной и т.п.?

    (19) Перестановки-то здесь при чем? Здесь задача: перебрать все слова длины L в алфавите из N букв. Слов таких, конечно, N**L.

    Reply
  22. see1c.ru

    (19) используя буквенный ряд А, Б, В, Г. Находим минимальное и максимальное числовое значение комбинаций.

    Разница между максимальным и минимальным значением будет равна их количеству.

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

    Reply
  23. tdr1225

    (21)

    верно, я ошибся, перестановки ни при чем

    Reply
  24. Ткачев

    (21)Потому что 0 это тоже число и нам надо получить на выходе все включенные разряды. 256 = 000000001, 255 = 11111111

    Я наверно в школе плохо учился, но я знаю только 4 системы счисления, 2, 8, 10, 16.

    Reply
  25. Арчибальд

    (24) Не заметил, что цикл от 0…

    http://www.computer-museum.ru/static/histussr/setun_b.htm

    Reply
  26. Гость

    очень интересная и полезная обработка,спасибо,очень кстати

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *