javascript 如何将数字分成整数部分,每个部分都是n的倍数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9776555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to divide number into integer pieces that are each a multiple of n?
提问by scubasteve
Had a hard time coming up with a concise title for this. I'm sure there are terms for what I want to accomplish and there is no doubt a common algorithm to accomplish what I'm after - I just don't know about them yet.
很难为此想出一个简洁的标题。我确信我想要完成的事情有一些条款,毫无疑问,有一个通用的算法可以完成我所追求的事情——我只是还不知道它们。
I need to break up a number into n pieces that are each a multiple of 50. The number is itself a multiple of 50. Here is an example: Divide 5,000 by 3 and end up with three numbers that are each multiples of 50:
我需要将一个数字分成 n 个,每个都是 50 的倍数。这个数字本身就是 50 的倍数。下面是一个例子:将 5,000 除以 3,最后得到三个数字,每个数字都是 50 的倍数:
- 1,650
- 1,700
- 1,650
- 1,650
- 1,700
- 1,650
I also would like to have the numbers distributed so that they flip back and forth, here is an example with more numbers to illustrate this: Divide 5,000 by 7 and end up with 7 numbers that are each multiples of 50:
我还希望数字分布,以便它们来回翻转,这里有一个带有更多数字的示例来说明这一点:将 5,000 除以 7,最终得到 7 个数字,每个数字都是 50 的倍数:
- 700
- 750
- 700
- 750
- 700
- 700
- 700
- 700
- 750
- 700
- 750
- 700
- 700
- 700
Note that in the above example I'm not worried that the extra 50 is not centered in the series, that is I don't need to have something like this:
请注意,在上面的示例中,我并不担心额外的 50 不在系列中居中,也就是说我不需要这样的东西:
- 700
- 700
- 750 <--- note the '50s' are centered
- 700
- 750 <--- note the '50s' are centered
- 700
- 700
- 700
- 700
- 750 <--- 注意“50s”居中
- 700
- 750 <--- 注意“50s”居中
- 700
- 700
Hopefully I've asked this clearly enough that you understand what I want to accomplish.
希望我已经问得够清楚了,你明白我想要完成什么。
Update: Here is the function I'll be using.
更新:这是我将使用的功能。
var number = 5000;
var n = 7;
var multiple = 50;
var values = getIntDividedIntoMultiple(number, n, multiple)
function getIntDividedIntoMultiple(dividend, divisor, multiple)
{
var values = [];
while (dividend> 0 && divisor > 0)
{
var a = Math.round(dividend/ divisor / multiple) * multiple;
dividend -= a;
divisor--;
values.push(a);
}
return values;
}
回答by sch
var number = 5000;
var n = 7;
var values = [];
while (number > 0 && n > 0) {
var a = Math.floor(number / n / 50) * 50;
number -= a;
n--;
values.push(a);
} // 700 700 700 700 700 750 750
Edit
编辑
You can alternate Math.floor
and Math.ceil
to obtain the desired result:
您可以交替使用Math.floor
并Math.ceil
获得所需的结果:
while (number > 0 && n > 0) {
if (a%2 == 0)
a = Math.floor(number / n / 50) * 50;
else
a = Math.ceil(number / n / 50) * 50;
number -= a;
n--;
values.push(a);
} // 700 750 700 750 700 700 700
回答by Mike Samuel
// i - an integer multiple of k
// k - an integer
// n - a valid array length
// returns an array of length n containing integer multiples of k
// such that the elements sum to i and the array is sorted,
// contains the minimum number of unique elements necessary to
// satisfy the first condition, the elements chosen are the
// closest together that satisfy the first condition.
function f(i, k, n) {
var minNumber = (((i / k) / n) | 0) * k;
var maxNumber = minNumber + k;
var numMax = (i - (minNumber * n)) / k;
var nums = [];
for (var i = 0; i < n - numMax; ++i) {
nums[i] = minNumber;
}
for (var i = n - numMax; i < n; ++i) {
nums[i] = maxNumber;
}
return nums;
}
So your second example would be
所以你的第二个例子是
f(5000, 50, 7)
which yields
这产生
[700,700,700,700,700,750,750]
回答by kilotaras
Let a be your starting number, k - number of parts you want to divide to.
Suppose, that b = a/n.
Now you want to divide b into k close integer parts.
让 a 成为你的起始数字,k - 你想要划分的部分数。
假设,b = a/n。
现在你想把 b 分成 k 个相近的整数部分。
- Take k numbers, each equal to b/k (integer division).
- Add 1 to first b%k numbers.
- Multiply each number by n.
- 取 k 个数字,每个数字都等于 b/k(整数除法)。
- 将 1 添加到第一个 b%k 数字。
- 将每个数字乘以 n。
Example:
a = 5000, n = 50, k = 7.
b = 100
Starting series {14, 14, 14, 14, 14, 14, 14}
Add 1 to first 2 integers {15, 15, 14, 14, 14, 14, 14}.
Multiply by 50 {750, 750, 700, 700, 700, 700, 700}.
示例:a = 5000, n = 50, k = 7.
b = 100
起始系列 {14, 14, 14, 14, 14, 14, 14}
将 1 添加到前 2 个整数 {15, 15, 14, 14, 14 , 14, 14}。
乘以 50 {750, 750, 700, 700, 700, 700, 700}。
回答by BlueRaja - Danny Pflughoeft
Your problem is the same as dividing a number X
into N
integer pieces that are all within 1 of each other (just multiply everything by 50 after you've found the result). Doing this is easy - set all N
numbers to Floor(X/N)
, then add 1 to X mod N
of them.
你的问题是一样的分割数X
为N
整数部件,它们都在彼此的1 (50只乘一切你已经找到了结果后)。这样做很容易 - 将所有N
数字设置为Floor(X/N)
,然后X mod N
在其中添加 1 。
回答by Manish
I see your problem as basically trying to divide a sum of money into near-equal bundles of bills of a certain denomination.
我认为您的问题基本上是试图将一笔钱分成几捆几乎相等的某种面额的钞票。
For example, dividing 10,000 dollars into 7 near-equal bundles of 50-dollar bills.
例如,将 10,000 美元分成 7 个几乎相等的 50 美元钞票。
function getBundles(sum, denomination, count, shuffle)
{
var p = Math.floor(sum / denomination);
var q = Math.floor(p / count);
var r = p - q * count;
console.log(r + " of " + ((q + 1) * denomination)
+ " and " + (count - r) + " of " + (q * denomination));
var b = new Array(count);
for (var i = 0; i < count; i++) {
b[i] = (r > 0 && (!shuffle || Math.random() < .5 || count - i == r)
? (--r, q + 1) : q)
* denomination;
}
return b;
}
// Divide 10,000 dollars into 7 near-equal bundles of 50-dollar bills
var bundles = getBundles(10000, 50, 7, true);
console.log("bundles: " + bundles);
Output:
输出:
4 of 1450 and 3 of 1400
bundles: 1400,1450,1450,1400,1450,1400,1450
If the last argument shuffle
is true
, it distributes the extra amount randomly between the bundles.
如果最后一个参数shuffle
是true
,它会在捆绑包之间随机分配额外的数量。
回答by Gennadii Saltyshchak
My algorithm provides even distribution of remainder across parts:
我的算法提供了跨部分的余数的均匀分布:
function splitValue(value, parts, multiplicity)
{
var result = [];
var currentSum = 0;
for (var i = 0; i < parts; i++)
{
result[i] = Math.round(value * (i + 1) / parts / multiplicity) * multiple - currentSum;
currentSum += result[i];
}
return result;
}
For value = 5000, parts = 7, multiplicity = 50 it returns
对于 value = 5000,parts = 7,multiplicity = 50,它返回
[ 700, 750, 700, 700, 700, 750, 700 ]
回答by Victor Sorokin
Here's my take:
这是我的看法:
public static void main(String[] args) {
System.out.println(toList(divide(50, 5000, 3)));
System.out.println(toList(divide(50, 5000, 7)));
System.out.println(toList(divide(33, 6600, 7)));
}
private static ArrayList<Integer> toList(int[] args) {
ArrayList<Integer> list = new ArrayList<Integer>(args.length);
for (int i : args)
list.add(i);
return list;
}
public static int[] divide(int N, int multiplyOfN, int partsCount) {
if (N <= 0 || multiplyOfN <= N || multiplyOfN % N != 0)
throw new IllegalArgumentException("Invalid args");
int factor = multiplyOfN / N;
if (partsCount > factor)
throw new IllegalArgumentException("Invalid args");
int parts[] = new int[partsCount];
int remainingAdjustments = factor % partsCount;
int base = ((multiplyOfN / partsCount) / N) * N;
for (int i = 0; i < partsCount; i ++) {
parts[i] = (i % 2 == 1 && remainingAdjustments-- > 0) ? base + N : base;
}
return parts;
}