1

我需要用给定的数字计算,有多少“五”、“二”和“一”可以进入这些数字。抱歉,我的英语对于这种解释有点有限:) 也许举个例子更好:

练习: print stamps(8) 结果应该是:(1, 1, 1) ( 一个 5p stamp, 一个 2p stamp 和一个 1p stamp)

我找到了实现这一目标的方法,但是 tuple() 正在打印结果和“无”,我不知道为什么。我也想知道是否有更好、更短的方法来获得正确的结果。

这就是我所做的:

def stamps(dinero):
    p5=dinero/5
    p5a=p5*5
    resultado1=dinero-p5a
    dinero=resultado1
    p2=dinero/2
    p2a=p2*2
    resultado2=dinero-p2a
    dinero=resultado2
    p1=dinero/1
    p1a=p1*1
    resultado3=dinero-p1a
    dinero=resultado3
    print tuple([p5,p2,p1])

我得到的结果是:print stamps(8) is (1, 1, 1) None

更新: 我找到了更好的解决方案,我将其发布在这里以防万一有人想知道更好的解决方案:

def stamps(n):
    #Basically, thats the same as return n/5, n%5/2, n%5%2
    return n/5, (n-5*(n/5))/2, (n-5*(n/5))-2*((n-5*(n/5))/2)
4

2 回答 2

2

正如人们所说,您可以将打印更改为返回,但是对代码的重大改进是使用%(或模)运算符。

def stamps(dinero):
    p5=dinero/5
    dinero=dinero%5
    p2=dinero/2
    dinero=dinero%2
    p1=dinero/1
    return tuple([p5,p2,p1])

print stamps(8)
>>> (1,1,1)

在您的代码中,这一行:

p5=dinero/5

执行整数除法,而下面通过将除数的倍数乘以原始数字并减去它来获得余数:

p5a=p5*5
resultado1=dinero-p5a
dinero=resultado1

大多数语言都提供了一个模函数,可以一步完成:

dinero=dinero%5

这对于除以 3 的部分是相同的,当除以 1 时,永远不会有整数余数,因此您可以完全删除该代码。

Python还有一种方法可以再次缩短它,使用divmod()它返回除数和模数:

def stamps(dinero):
    p5,dinero=divmod(dinero,5)
    p2,dinero=divmod(dinero,2)
    p1=dinero
    return tuple([p5,p2,p1])

print stamps(8)
>>> (1,1,1)

最后,您可以完全通用化它,方法是让另一个函数同时获取数量和邮票值数组并调用它:

def stamps(dinero):
    return allStamps(dinero,[5,2,1])

def allStamps(dinero=1,stamps=[]):
    vals = []
    for stamp in sorted(list(set(stamps)), reverse=True):
        val,dinero=divmod(dinero,stamp)
        vals.append(val)
    return tuple(vals)

print stamps(8)
>>> (1,1,1)
print allStamps(8,[5,3,1])
>>> (1,1,0)

关于代码执行速度:

我在一些选项上运行了一个timeit,并且调用/%结果甚至比单个调用更快divmod()

> python -m timeit 'a=1000;b=a/5;c=b*5;d=a-c;a=d'
 10000000 loops, best of 3: 0.156 usec per loop
> python -m timeit 'a=1000;b=a/5;a=a-b*5;'
 10000000 loops, best of 3: 0.127 usec per loop
> python -m timeit 'a=1000;a=a-(a/5)*5;'
 10000000 loops, best of 3: 0.121 usec per loop
> python -m timeit 'a=1000/13;b=1000%13;'
 10000000 loops, best of 3: 0.0755 usec per loop
root@meteordev:~# python -m timeit 'a,b=divmod(1000,13);'
 10000000 loops, best of 3: 0.183 usec per loop
于 2013-07-22T01:42:19.100 回答
0

在你的函数中将“print”更改为“return”,当你调用“print stamps(8)”时应该可以修复它。此外,不,对于您简单地选择标记值 5、2、1,除了您正在做的事情之外,没有更有效的方法可以找到一个好的解决方案(如果您有,唯一可能的改进可能是使用 for 循环更多的邮票值不仅仅是 3) - 如果您的邮票值更复杂,那么您可以通过使用动态编程找到使用更少邮票的更好解决方案。

于 2013-07-22T01:33:27.230 回答