假設有一個由 x 個數字組成的陣列,它們的總和是 100。
每個數字都隨著步長線性增加或減少。每次數字增加時,其余部分必須均勻減少 ,以使數字總和不超過 100。同樣,每次數字減少時,其余部分必須均勻增加,以使數字總和不低于 100。如果某個值導致總和超過或低于 100,則必須禁止該操作并向用戶發送訊息。
假設那個陣列A: [20,20,20,20,20]
A[2] = 4
//the array A has to become somehow automatically: [19,19,24,19,19]
這有3個問題。首先,如果一個數字超過一個值,那會使其余的值低于 0,我不希望這樣。例子:
A: [-5,100,-5,-5,-5]
另一個與步驟有關。我不知道它應該增加或減少多少(可能基于陣列的長度)。
現在我有step = 1 / A.length
因此,如果一個數字隨著step增加,其余部分必須減少step / A.length - 1(減去一個原因我不計算用戶更改的數字)
反之亦然
基本上我正在嘗試根據用戶價值(向下或向上)進行百分比遞增或遞減。你能給我建議我必須遵循的邏輯,或者一些 JavaScript 代碼嗎?
編輯:
我已經用角度實作了一些東西。
起初,這些值都相等,總和為 100:

如果我用按鈕( > )增加第一個數字,其余的將減少,依此類推..

我沒有發布代碼,因為它有問題并且非常復雜,我只想要代碼中的邏輯或范例,以便我可以在我的應用程式中實作它。數字中的復選框旨在鎖定該值,使其不會增加或減少。
uj5u.com熱心網友回復:
您可以檢查是否存在遞減值并將所有更改添加到總和以遞增值。
const
change = (array, index, direction) => {
if (direction === 1) {
const step = 1 / array.length;
for (let i = 0; i < array.length; i ) {
if (i === index || array[i] === 0) continue;
const s = Math.min(step, array[i]);
array[i] -= s;
array[index] = s;
}
} else {
const step = Math.min(1 / array.length, array[index] / (array.length - 1));
for (let i = 0; i < array.length; i ) {
if (i === index) continue;
array[i] = step;
array[index] -= step;
}
}
return array;
},
values = [96.8, 0.2, 1, 1, 1],
display = values => values.forEach((v, i) => document.getElementById('value' i).innerHTML = v.toFixed(2)),
addEvent = (type, index) => event => {
change(values, index, type === 'up' ? 1 : -1);
display(values);
};
[...document.getElementsByTagName('button')].forEach(element => {
const [type, index] = element.id.match(/\d |\D /g);
element.addEventListener('click', addEvent(type, index));
});
display(values);
.as-console-wrapper { max-height: 100% !important; top: 0; }
td { text-align: center; width: 20%; }
<table>
<tr>
<td><button id="up0">^</button></td>
<td><button id="up1">^</button></td>
<td><button id="up2">^</button></td>
<td><button id="up3">^</button></td>
<td><button id="up4">^</button></td>
</tr>
<tr>
<td id="value0"></td>
<td id="value1"></td>
<td id="value2"></td>
<td id="value3"></td>
<td id="value4"></td>
</tr>
<tr>
<td><button id="down0">v</button></td>
<td><button id="down1">v</button></td>
<td><button id="down2">v</button></td>
<td><button id="down3">v</button></td>
<td><button id="down4">v</button></td>
</tr>
</table>
uj5u.com熱心網友回復:
詳細評論示例如下
// Utility function
const log = data => console.log(JSON.stringify(data));
const arr1 = [20, 20, 20, 20, 20];
const arr2 = [-5, 115, -5, -5];
/**@function
*@name incDec
*@description Increase/decrease a number by the given index of a given
* array by a given number and inversely decrease/increase the rest of
* the numbers evenly until the sum of all numbers within the array is
* the same as it was originally.
*@param {number} index - Index number of the number being changed.
*@param {number} by - Number to decrease/increase first parameter by.
*@param {array<number>} array - The array of numbers
*@returns {array<number>} A new array of modified numbers
*/
const incDec = (index, by, array) => {
/*
Chrome doesn't divide negative numbers correctly.
Simple divison in of itself needs to be simplified.
So a ? will denote this as the reason.
*/
let mod = Math.abs(by);
/*
Return a new array with the targeted number modified by >by<.
*/
const newArr = array.map((num, idx) => idx == index ? num by : num);
const div = array.length - 1; //?
/*
Divide the number it changed by, by the number of remaining numbers
in the array.
*/
let quo = mod / div;
quo = by < 0 ? -Math.abs(quo) : quo; //?
// Return a new array that has the modified numbers.
return newArr.map((num, idx) => idx == index ? num : num - quo);
};
log(incDec(3, 8, arr1));
log(incDec(2, -8, arr2));
.as-console-row::after {
width: 0;
font-size: 0;
}
.as-console-row-code {
width: 100%;
word-break: break-word;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/446417.html
標籤:javascript 数组 算法
上一篇:如何從陣列中洗掉多個元素?
下一篇:給定一個數字,找到到達它的序列
