将一个数字分成(几乎)相等的整数的算法

11

我有这样一种情况:我接收到的发票电子表格只有一行,但跨越了多个月份,其中包含一个数量列,该列包含跨越所有月份的数量总和。

为了进行逐月分析,我们需要将总数量分成n行相等(或近似相等)的数量,其中n是跨度的月份数。

这些数字可能会有一两个出入,但每个元素之间的差异越小越好。

我在Python中制作了一个初步的模型,但我感觉还有更好的方法来解决这个问题。注意:请原谅...一切:

from __future__ import division
import math
def evenDivide(num, div):
    splits = []
    sNum = str(num/div)
    remainder = float(sNum[sNum.index('.'):])
    #print "Remainder is " + str(remainder)
    integer = math.floor(num/div)
    #print "Integer is " + str(integer)
    totRemainder = round(remainder * div, 2)
    #print "Total Remainder is " + str(totRemainder)
    for index in range(div):
        if (totRemainder > 0):
            totRemainder -= 1 if (index%2 == 0) else 0
            if (index % 2 == 0):
                splits.append(int(integer + 1)) 
            else:
                splits.append(int(integer))
        else:
            splits.append(int(integer))
    for index in range(div):
        if(totRemainder > 0):
            if (index % 2 == 1):
                splits[index] += 1
                totRemainder -= 1

    return splits

def EvalSolution(splits):
    total = 0
    for index in range(len(splits)):
        total += splits[index]
    return total

def testEvenDivide():
    for index in range(20000):
        for jndex in range(3, 200):
            if (EvalSolution(evenDivide(index, jndex)) != index):
                print "Error for " + str(index) + ", " + str(jndex)

问题是什么?你的代码达到了预期效果吗?如果是的话,您应该在http://codereview.stackexchange.com上发布。 - usethedeathstar
你能给出示例输入/输出吗? - Dogbert
4个回答

17

如果空间有限的话,这个一行代码可能会有所帮助:

num, div = 15, 4
print ([num // div + (1 if x < num % div else 0)  for x in range (div)])
# result: [4, 4, 4, 3]

3
  1. [num // div for x in range (div)] 创建一个由div个数字组成的列表,每个数字都等于num/div,例如[3,3,3,3];
  2. (1 if x < num % div else 0) 只在前num%div个元素中添加1,例如[1,1,1,0];
将上述两个操作结合起来得到的结果是[4,4,4,3]。
- Poe Dator

6

我假设num和div都是整数(你应该在问题中提到它)。

您可以使用模运算符找到除法的余数:

remainder=num%div   # i.e. 124/12 will give you 4

整数除法将给你结果的整数部分,而不使用 math.floor 函数。

integer = num/div    # i.e. 124/12 will give you 10

我现在可以返回一个(整数,余数)元组,但如果你真的需要将所有分割存储在列表中,你可以这样做:

splits=[]
for i in range(div):
   splits.append(integer)
for i in range(remainder):
   splits[i]+=1

1
顺便提一下,Python内置了一个名为divmod()的函数,非常适合完成第一部分。 - martineau

2
这个一行代码可以帮助你:
def get_evenly_divided_values(value_to_be_distributed, times):
    return [value_to_be_distributed // times + int(x < value_to_be_distributed % times) for x in range(times)]

1
这是对Poe Dator's答案的一种变化,它避免了对每个返回的数字进行模运算:
def evenDivide(num, div):
    groupSize, remainder = divmod(num, div)
    return [groupSize + (1 if x < remainder else 0) for x in range(div)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接