繁体   English   中英

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

[英]Algo for dividing a number into (almost) equal whole numbers

我有一种情况,我收到的发票电子表格包含跨越多个月的单行,其中一个数量列包含跨越所有月份的数量总和。

为了运行逐月分析,我们需要将总数量分成 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)

如果空间是一个问题,这条单线可能会有所帮助:

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

我假设 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

我现在会返回 (integer,remainder) 元组,但如果你真的需要列表中的所有拆分,你可以这样做:

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

这一个衬垫可以帮助:

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)]

这是Poe Dator 的答案的一个变体,它避免对每个返回的数字进行模数运算:

def evenDivide(num, div):
    groupSize, remainder = divmod(num, div)
    return [groupSize + (1 if x < remainder else 0) for x in range(div)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM