Как перебрать массив чисел, чтобы увидеть, какие числа имеют отношение к другому числу? - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь написать простую программу на ванильном JavaScript для тяжелой атлетики.Пользователь вводит определенное количество веса, и он возвращает таблички определенного веса, чтобы положить их на каждую сторону штанги.

Затем я принимаю это число в функцию, которая вычитает 45 из него, чтобы учесть вес штанги, а затем делит это число на 2, которое является количеством веса, которое нужно положить на каждую сторону стержня.

const num = document.getElementById("weightAmount").value;

function getWeightAmount (num) {
const newNum = num - 45;
const halfNum = newNum / 2;
return getWeights(halfNum);
}

У меня есть массив с каждой табличкой весов:

let plates = [44, 33, 22, 11, 5.5, 2.75];

У меня возникают проблемы с правильным циклом просмотра массива, чтобы получить то, что я хочу.Если мне нужно, скажем, 60,5 фунтов с каждой стороны, он должен вернуть 44, 11, 5,5.Поэтому мне нужно выяснить, какие числа в массиве plate соответствуют числу, возвращенному из моей первой функции.

У меня есть пустой массив с именем weights, в который я хочу вставить числа из массива plates в эту работу с весом, который затем возвращается.

Мой вопрос: как сделатьЯ перебираю массив plates, чтобы выяснить, какие веса нужны?

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

У меня есть простое решение ниже, если значение целевого веса всегда будет суммой доступных тарелок.Предполагая, что массив весов отсортирован в порядке убывания.Я зациклился на всех доступных весах и перейду к следующему весу, только если общий вес превысит общий вес, который вам требуется.

function getWeights(targeWeight) {

    let plates = [44, 33, 22, 11, 5.5, 2.75];

    let totalWeight = 0;

    let neededPlates = [];

    let i = 0;

    while(i < plates.length){

        var pweight = totalWeight + plates[i];

        if (pweight > targeWeight) {
            i++;
            continue;
        }

        totalWeight += plates[i];
        neededPlates.push(plates[i]);
    }

    return neededPlates;
}

console.log(getWeights(60.5)); // [44, 11, 5.5]
console.log(getWeights(104.5)); //[44, 44, 11, 5.5]
0 голосов
/ 25 февраля 2019

Возможным решением этой проблемы является итерация до бесконечности, пока либо

  • у вас не будет решения
  • проблема станет неразрешимой, учитывая набор весов

На каждом шаге итерации вы вычитаете максимально возможный вес, умноженный на максимально возможный коэффициент, сохраняете как в подходящей структуре данных (моя реализация просто использует Object), так и продолжаете.

const plates = [44, 33, 22, 11, 5.5, 2.75];

// We assume that plates is always sorted
const determineWeights = (totalWeight) => {
  let factor = 0;
  let weights = {};

  while (totalWeight > 0) {
    weight = plates.find(weight => Math.floor(totalWeight / weight) > 0);

    // There is no weight we can subtract from the total weight to solve the problem
    // Hence, the problem is unsolvable and we return null to indicate that no solution exists
    if (!weight) { return null; }

    // Determine the factor with which to multiply the weight before we subtract from the total weight an subtract the product
    factor = Math.floor(totalWeight / weight);
    totalWeight = totalWeight - factor * weight;

    // Store weight and factor
    weights[weight] = factor;
  }
  
  return weights;
}


console.log(determineWeights(104.5)); // { "11": 1, "44": 2, "5.5": 1 }
console.log(determineWeights(60.5)); // { "11": 1, "44": 1, "5.5": 1 }
console.log(determineWeights(5.0)); // null

Эта проблема, по сути, является экземпляром проблемы с ранцем .

Обратите внимание, что мы предполагаем, что plates отсортировано.В противном случае Array.find не обязательно будет извлекать максимальный вес, который можно вычесть из общего веса.

0 голосов
/ 25 февраля 2019

Вот решение.В случае, если доступные тарелки не складываются с целевым весом, он вернет комбинацию доступных тарелок, которые складываются ближе всего к цели.Адаптировано с этот ответ .

function createSubsets(numbers, target) {
    // filter out all items larger than target
    numbers = numbers.filter(function (value) {
        return value <= target;
    });

    // sort from largest to smallest
    numbers.sort(function (a, b) {
        return b - a;
    });

    var i;
    var sum = 0;
    var addedIndices = [];

    // go from the largest to the smallest number and
    // add as many of them as long as the sum isn't above target
    for (i = 0; i < numbers.length; i++) {
        if (sum + numbers[i] <= target) {
            sum += numbers[i];
            addedIndices.push(i);
        }
    }

    return addedIndices.map(n => numbers[n]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...