Прохождение двух списков с двумя проверками

#python-3.x

Вопрос:

Функция принимает три параметра:

  1. Список номеров, относящихся к стоимости ноутбуков
  2. Список строк, указывающих, неисправен ноутбук или нет, т. е. является ли он «законным» или «незаконным»
  3. Целое число, обозначающее количество ноутбуков, которые будут выпущены в день.

Так что, если ввод-это что-то вроде:

 cost = [1,3,2,5,4,1]
labels = ['legal', 'illegal', 'legal', 'legal', 'legal', 'legal']
dailyCount = 2
 

Результатом должна быть общая максимальная стоимость, понесенная, следовательно, за первый день стоимость =(1 3 2) т. е. 6. Мы также подсчитываем стоимость нелегального товара. На второй день появляются следующие две записи, поэтому стоимость= (5 4), т. е. 9. Следующей записи(последней оставшейся) недостаточно для ежедневного подсчета, поэтому мы оставляем это. Следовательно, общая максимальная понесенная стоимость составляет 6 9 = 15. Который возвращает функция.
Вот как далеко я продвинулся после многих часов:

     def maxCost(cost, labels, dailyCount):
        count = 0 #counts the number of legal laptops made
        money = 0 #counts daily cost incurred
    
        def calc(labels, count, money):
            if len(labels) > 0:
                for i in range(len(labels)):
                    money  = cost[i]
                    if labels[i] == 'legal':
                        count  = 1
                    if count == dailyCount:
                        calc(labels[i:], 0, money)
            return money
        
        res = calc(labels,count,money)
        return res
cost = [1,2,4,3]
labels = ['legal','illegal','legal','legal']
dailyCount = 2
print(maxCost(cost, labels, dailyCount))
 

Результат должен быть равен 5. Но он показывает 10, я не знаю как?

Комментарии:

1. Какова связь между опубликованным вами кодом и поведением, которое вы хотите от него получить?

2. Отредактировал его. Посмотрим, имеет ли это смысл сейчас.

3. Ваши if тесты на «ярлык»…. что не является значением, которое возникнет.

4. почему бы этому не произойти?

5. Просто посмотри на это. Написание. Но есть и другие проблемы…

Ответ №1:

Проблемы:

  • Рекурсивный вызов (если он будет выполнен) возвращает денежную сумму, но вы игнорируете это значение, так как вы ничему его не присваиваете.
  • Ваш код, по-видимому, предполагает, что вы думаете, что параметры (иногда) являются ссылками на переменные вызывающего объекта и что изменение, скажем, money повлияет на внешнюю money переменную, но это не так. Все аргументы передаются локальным переменным, и любое их присвоение не отражается в переменной, переданной в качестве аргумента.
  • count следует сбрасывать значение до 0 каждый раз, когда вы достигаете полной стоимости дня. Таким count образом, может быть локальная переменная calc функции. Он не должен быть определен в другом месте и не должен передаваться в качестве аргумента (в любом случае вы всегда передаете 0, так что это не очень полезно).
  • В настоящее money время не накапливается за разные дни. Для накопления используйте возвращаемое значение и добавьте его в локальную money переменную вызывающего объекта. Опять же, это не нужно передавать money в качестве аргумента. Пусть каждый звонок возвращает деньги, которые относятся к его делу, и пусть звонящий добавит к этому стоимость своего дня.
  • Нет никакой проверки того, что вы получили полное количество ноутбуков за последний день. Если нет, то уже накопленное money следует игнорировать. Поэтому было бы хорошо сразу вернуться после рекурсивного вызова. Если затем цикл for завершится без выполнения этого нового возврата, то мы знаем, что количество выпущенных ноутбуков было недостаточным, и мы должны это сделать return 0 .
  • В рекурсивном вызове вы передаете [i:] , но i он уже обработан, поэтому вы должны нарезать [i 1:] .
  • Ваш рекурсивный вызов получает срезанный labels список, но cost не срезан, поэтому индекс i больше не выровнен должным образом, и при захвате cost[i] вы не получаете стоимость, связанную с i индексом в срезанном labels списке. Поэтому вместо нарезки я бы предложил вам передать i индекс ( i 1 )
  • Правильный вывод для последнего примера кода также не должен быть равен 5: он должен быть равен 7, поскольку следует учитывать «незаконную» стоимость второго ноутбука.

Это немного излишне, чтобы решить эту проблему с помощью рекурсии, но я оставлю это на месте в этой версии:

 def maxCost(cost, labels, dailyCount):
    def calc(start):
        count = 0
        money = 0
        if len(labels) > 0:
            for i in range(start, len(labels)):
                money  = cost[i]
                if labels[i] == 'legal':
                    count  = 1
                if count == dailyCount:
                    return money   calc(i 1)
        return 0 # not enough labels
    
    res = calc(0)
    return res
 

В качестве альтернативы, вот решение, которое сначала подсчитывает количество легальных ноутбуков, затем определяет, сколько их должно быть произведено (должно быть кратно ежедневному количеству), затем ищет индекс этого последнего легального ноутбука и, наконец, суммирует затраты на этот ноутбук:

 def maxCost(cost, labels, dailyCount):
    numlegals = sum(1 for label in labels if label == 'legal')

    # truncate to a multiple of dailyCount
    numlegals -= numlegals % dailyCount
    for i, label in enumerate(labels):
        if label == 'legal':
            numlegals -= 1
            if numlegals == 0:
                return sum(cost[:i 1])