Рекурсивный перевод функции Python в Javascript не работает, проблема с массивами

1

Я хочу перевести программу Python (которая решает определенную основную комбинаторную проблему) в Javascript. Цель состоит в том, чтобы оценить my_function (200, [1,2,5,10,20,50,100,200]), и результатом является то, что программа Python вернет правильный ответ (~ 70k), но моя попытка перевода Javascript возвращает неверный ответ (~ 60k).

Функция my_function определяется рекурсивно, и, в частности, второй вход, список, усекается на этапе рекурсии (см. Вторую строку кода). Возможно, я не справился с этим в версии JS.

Функция Python:

import math

coin_sizes = [1,2,5,10,20,50,100,200]

def my_function(amount, coins_list):
    if amount == 0:
        return 1
    elif len(coins_list) == 0:
        return 0
    elif len(coins_list) == 1:
        return 1
    else:
        top_coin = coins_list[-1]
        d = math.floor(amount/top_coin)
        total = 0
        for i in range(0,d+1):
            total += my_function(amount - i*top_coin, coins_list[:-1])
        return total

Функция Javascript:

var coin_sizes = [1,2,5,10,20,50,100,200];

var sublist = function(mylist) {
    var new_list = Array(mylist.length-1);
    for (var i = 0; i < mylist.length-1; i++){
        new_list[i] = mylist[i];
    }
    return new_list
};

var my_function = function(amount, coins_list) {
    if (amount == 0) return 1;
    else if (coins_list.length == 0) return 0;
    else if (coins_list.length == 1) return 1;
    else {
        var top_coin = coins_list[(coins_list.length-1)];
        d = Math.floor(amount/top_coin);
        var total = 0;
        for (var i = 0; i < d+1; i++) {
        total += my_function(amount - i*top_coin, sublist(coins_list));
        };
        return total;
    };
};

Я попытался написать аналогичную программу на Java, но получил слишком много ошибок.

Вопрос: Что происходит? Почему я получаю неправильный ответ, и есть ли лучший способ перевести эту программу Python на Javascript?

Примечание. Исходная комбинаторная проблема может быть решена динамически/без рекурсии, и тогда у меня не возникло бы проблемы с ее переводом на Javascript. Я хочу научиться писать что-то подобное функции Python выше.

  • 0
    Я не смог выяснить, где это идет не так, но я видел, что отрицательные значения для amount передаются в версию JS, но не в версию Python, когда вызывается с количеством = 20. Должно быть что-то с циклом for и вычитанием i * top_coin, которое расходится в импланте JS ...
  • 0
    Спасибо, я этого не видел.
Теги:
arrays
math
recursion

1 ответ

2
Лучший ответ

Вы пропустите объявление d.

Кстати, вы могли бы использовать раннюю парадигму выхода, if... return... и продолжаться без else и для последнего блока, вам нужно объявить все переменные, потому что если нет, переменная является глобальной и значение изменяется с помощью рекурсивного вызова,

Другой намек, после блочных операторов {... }, как и for или else, вам не нужна точка с запятой.

И, наконец, вы можете использовать Array#slice для получения копии с начала до конца - 1, используя -1 относительно параметра (второй).

var coin_sizes = [1, 2, 5, 10, 20, 50, 100, 200],
    sublist = function(mylist) {
        return mylist.slice(0, -1);
    },
    my_function = function(amount, coins_list) {
        if (amount == 0) return 1;
        if (coins_list.length == 0) return 0;
        if (coins_list.length == 1) return 1;
        var top_coin = coins_list[(coins_list.length - 1)],
            d = Math.floor(amount / top_coin),
            total = 0;
        for (var i = 0; i < d + 1; i++) {
            total += my_function(amount - i * top_coin, sublist(coins_list));
        }
        return total;
    };

console.log(my_function(200, [1, 2, 5, 10, 20, 50, 100, 200]));
  • 0
    Вау, спасибо - это так полезно!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню