SICP внесение изменения

испытайте это:

System.Collections.ObjectModel.Collection<BusinessObject>

это делает ненужным для реализации основного метода как CollectionBase, делают

13
задан sarnold 13 April 2012 в 01:42
поделиться

3 ответа

Самый простой / самый общий способ избавиться от рекурсии, как правило, - использовать вспомогательный стек - вместо рекурсивных вызовов вы помещаете их аргументы в стек и выполняете итерацию. Когда вам нужен результат рекурсивного вызова для продолжения, опять же в общем случае, это немного сложнее, потому что вам также понадобится возможность отправить «запрос продолжения» (который будет исходить из вспомогательного стек, когда результаты известны); однако в этом случае, поскольку все, что вы делаете со всеми результатами рекурсивного вызова, является суммированием, достаточно сохранить аккумулятор, и каждый раз, когда вы получаете числовой результат вместо необходимости выполнять дополнительные вызовы, добавляйте его к аккумулятор.

Однако это, по сути, не фиксированное пространство, поскольку этот стек будет расти. Итак, еще одна полезная идея: поскольку это чистая функция (без побочных эффектов), каждый раз, когда вы обнаруживаете, что вычислили значение функции для определенного набора аргументов, вы можете запоминать соответствие аргумента-результат. Это ограничит количество звонков. Другой концептуальный подход, который приводит почти к таким же вычислениям, - это динамическое программирование [[aka DP]], хотя с DP вы часто работаете снизу вверх, так сказать, «подготавливая результаты для запоминания», а не начинаете с рекурсией и работаем над ее устранением.

Возьмем, к примеру, восходящий DP для этой функции. Вы знаете, что в конечном итоге вы постоянно будете спрашивать «сколько способов внести сдачу на сумму X с помощью самой маленькой монеты» (когда вы сокращаете все до X с помощью различных комбинаций монет из исходного количества ), вы начинаете вычислять эти значения amount с помощью простой итерации (f (X) = X / значение , если X точно делится на значение наименьшего достоинства монеты , иначе 0 ; здесь значение равно 1, поэтому f (X) = X для всех X> 0). Теперь вы продолжите, вычисляя новую функцию g (X), способы внести изменения для X с помощью двух наименьших монет: снова простая итерация для увеличения X, с g (x) = f (X) + g (X - значение ) для значения второй по величине монеты (это будет простая итерация, потому что к тому времени, когда вы вычисляете g (X), вы Мы уже вычислили и сохранили f (X) и все g (Y) для Y тремя наименьшими монетами - h (X) = g (X) + g (X- значение ) как выше - и с этого момента f (X) вам больше не понадобится, поэтому вы можете повторно использовать это пространство. В общем, для этого потребуется пространство 2 * количество - еще не «фиксированное пространство», но, подойдя ближе ...

Чтобы совершить последний прыжок в «фиксированное пространство», спросите себя: делайте вам нужно сохранить около всех значений двух массивов на каждом шаге (последнего вычисленного и вычисляемого в данный момент) или только некоторых из этих значений, немного переставить петлю ...?

g (X) = 0 для всех X <= 0). И снова для h (X), способы внести изменения для X с тремя наименьшими монетами - h (X) = g (X) + g (X- значение ) как выше - и с этого момента f (X) вам больше не понадобится, поэтому вы можете повторно использовать это пространство. В общем, для этого потребуется пространство 2 * количество - еще не «фиксированное пространство», но, подойдя ближе ...

Чтобы совершить последний прыжок в «фиксированное пространство», спросите себя: делайте вам необходимо сохранить около всех значений двух массивов на каждом шаге (последнего вычисленного и вычисляемого в данный момент) или только некоторых из этих значений, немного переставив петлю ...?

g (X) = 0 для всех X <= 0). И снова для h (X), способы внести изменения для X с тремя наименьшими монетами - h (X) = g (X) + g (X- значение ) как выше - и с этого момента f (X) вам больше не понадобится, поэтому вы можете повторно использовать это пространство. В общем, для этого потребуется пространство 2 * количество - еще не «фиксированное пространство», но, подойдя ближе ...

Чтобы совершить последний прыжок в «фиксированное пространство», спросите себя: делайте вам необходимо сохранить около всех значений двух массивов на каждом шаге (последнего вычисленного и вычисляемого в данный момент) или только некоторых из этих значений, немного переставив петлю ...?

способы внести размен для X с помощью трех наименьших монет - h (X) = g (X) + g (X- значение ), как указано выше - и теперь вы f (X) больше не понадобится, поэтому вы можете повторно использовать это пространство. В общем, для этого потребуется пространство 2 * количество - еще не «фиксированное пространство», но, подойдя ближе ...

Чтобы совершить последний прыжок в «фиксированное пространство», спросите себя: делайте вам необходимо сохранить около всех значений двух массивов на каждом шаге (последнего вычисленного и вычисляемого в данный момент) или только некоторых из этих значений, немного переставить петлю ...?

способы внести размен для X с помощью трех наименьших монет - h (X) = g (X) + g (X- значение ), как указано выше - и теперь вы f (X) больше не понадобится, поэтому вы можете повторно использовать это пространство. В общем, для этого потребуется пространство 2 * количество - еще не «фиксированное пространство», но, подойдя ближе ...

Чтобы совершить последний прыжок в «фиксированное пространство», спросите себя: делайте вам нужно сохранить около всех значений двух массивов на каждом шаге (последнего вычисленного и вычисляемого в данный момент) или только некоторых из этих значений, немного переставив петлю ...?

12
ответ дан 2 December 2019 в 00:58
поделиться

Вы можете решить эту проблему итеративно с помощью динамического программирования за псевдополиномиальное время.

-2
ответ дан 2 December 2019 в 00:58
поделиться

Решение, которое я придумал, состоит в том, чтобы вести подсчет каждого типа монет, которые вы используете в "кошельке"

Основной цикл работает следующим образом; 'denom - текущий номинал, 'changed - общая стоимость монет в кошельке, 'given - количество сдачи, которое мне нужно сделать, и 'clear-up-to вынимает из кошелька все монеты меньше заданного номинала.

#lang scheme
(define (sub changed denom)
  (cond
   ((> denom largest-denom)
    combinations)

   ((>= changed given)
    (inc-combinations-if (= changed given))

    (clear-up-to denom)
    (jump-duplicates changed denom)) ;checks that clear-up-to had any effect.

   (else
    (add-to-purse denom)
    (sub
     (purse-value)
     0
     ))))

(define (jump-duplicates changed denom)
  (define (iter peek denom)
    (cond
     ((> (+ denom 1) largest-denom)
      combinations)

     ((= peek changed)
      (begin
        (clear-up-to (+ denom 1))
        (iter (purse-value) (+ denom 1))))

      (else
       (sub peek (+ denom 1)))))
  (iter (purse-value) denom))

После прочтения ответа Алекса Мартелли я придумал идею кошелька, но только сейчас дошел до того, чтобы заставить его работать

.
1
ответ дан 2 December 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: