我在使用Python 2计算任何乘法问题中的进位数时遇到了麻烦。我试图调整一个我已经制作的程序,其中包含任何附加问题,但我似乎仍然无法使其工作。我目前正在学习Python的基础知识,所以我使用非常简单的东西。任何有关如何转换此程序以应用于乘法的指针都将不胜感激!
这是我计算附加程序:
if len(str(x)) != len(str(y)):
if len(x) > len(y):
while len(x) > len(y):
y = '0' + y
else:
while len(y) > len(x):
x = '0' + x
z = int(x) + int(y)
counter = 0
carries = 0
i = len(str(x))
while i > 1:
i -= 1
added = int((x[i])) + int((y[i])) + counter
if added > 9:
carries +=1
counter = 1
else:
counter = 0
print str(x), '+', str(y), '=', z
print 'Number of carries: ', str(carries)
答案 0 :(得分:1)
我假设通过载数的数量你想知道进位发生了多少次,而不是进位的总和。例如,34 x 48第一步将有一个乘法进位(乘以4和8时为3),即使总携带值等于3。
此外,我假设您还想知道进行乘法时发生的加法进位数。继续我们的例子,当我们乘以34 * 40时,我们有一个乘法进位(4 * 4)。我们现在必须添加两个结果(272和1360)。这将导致一次加法进位,进位运算总数等于3。
基本上,我计算了总数,不包括超过最大数量。这意味着90 * 9不会有任何携带。同样,90 + 99也没有任何进位。我决定了这种行为,根据你的加法如何运作。如果你不是故意要发生这种情况,并希望包括最后一位的进位,只需按照**** ... ****
评论中注明的代码更改。
代码如下。我包括了我自己的计算附加执行的实现。它应该在功能上等同于您发布的代码。
def num_add_carries(x, y):
"""
Return a count of the number of addition carries.
@param x: A number to add, as an integer.
@param y: A number to add, as an integer.
@return: The total number of carry operations.
"""
# Determine which number is the larger one
if y <= x:
min_num = y; max_num = x
else:
min_num = x; max_num = y
# Initialize some parameters
num_carries = 0
smin = str(min_num); smin_length = len(smin)
smax = str(max_num); smax_length = len(smax)
# Determine the end looping parameter
# **** Set to '-1' to include the end carry ****
end_ix = -1 if smin_length != smax_length else 0
# Iteratively perform the multiplication, counting the mult carries
for i, ix in enumerate(xrange(smin_length - 1, end_ix, -1), 1):
if int(smax[-i]) + int(smin[ix]) > 9:
num_carries += 1
return num_carries
def num_mult_carries(x, y):
"""
Return a count of the total number of multiplication carries, including
all necessary addition carries.
@param x: A number to add, as an integer.
@param y: A number to add, as an integer.
@return: The total number of carry operations.
"""
# Determine which number is the larger one
if y <= x:
min_num = y ; max_num = x
else:
min_num = x; max_num = y
# Initialize some parameters
num_carries = 0; adds = [] # List of numbers to add
smin = str(min_num); smin_length = len(smin)
smax = str(max_num); smax_length = len(smax)
# Iteratively perform the multiplication, counting the mult carries
for i, ix in enumerate(xrange(smin_length - 1, -1, -1)):
# Perform Multiplication (used for summing, later)
adds.append(max_num * int(smin[ix]) * (10 ** i))
# Determine number of multiplication carries
# **** Change the '0' to '-1' to include the end carry ****
for ix2 in xrange(smax_length - 1, 0, -1):
if int(smax[ix2]) * int(smin[ix]) > 9:
num_carries += 1
# Iteratively perform the addition, counting the addition carries
s = 0
while len(adds) > 1:
s += adds.pop(0)
num_carries += num_add_carries(s, adds[0])
return num_carries
print num_add_carries(99, 99)
print num_mult_carries(657, 34)
上述代码的输出是:
1
6
答案 1 :(得分:1)
我做了与@TehTechGuy相同的假设,尽管我以不同的方式解决了问题。我选择使用递归方法而不是迭代方法,因为对于那些类型的问题它更自然。
如果我们计算在加法阶段发生的进位,那么我们需要在方法中封装用于计算加法进位的逻辑,如下所示:
def count_addition_carries_rec(nums, answer=0, carries=0):
dig_count = max(len(str(nums[0])), len(str(answer)))
carries_list = [0]
new_answer = ''
# convert to string, apply left-padding, and reverse
rnums = [str(x).zfill(dig_count)[::-1] for x in [nums[0], answer]]
for i in range(dig_count):
dig_sum = str(sum([int(num[i]) for num in rnums]) + carries_list[i])
if i < dig_count - 1:
new_answer = dig_sum[-1] + new_answer
carries_list.append(int(dig_sum[:-1].zfill(1)))
else:
new_answer = dig_sum + new_answer
carries_list = [car for car in carries_list if car != 0]
if len(nums) == 1:
# If this is the last number in the list,
# return the answer and the number of carries that
# occurred in the current as well as previous operations.
return int(new_answer), carries + len(carries_list)
else:
# if there are more numbers in the list,
# repeat the operation with a sublist, consisting of the next
# number onwards, passing the current sum (new_answer) and
# the current count of carries
return count_addition_carries_rec(nums[1:],
new_answer,
carries + len(carries_list))
count_addition_carries_rec
方法是通用的,因为它可能需要2个以上的整数。 nums参数是一个列表,该方法期望长度为2或更长。
计算乘法运算的方法如下:
def count_multiplication_carries_rec(num1, num2, answer=0, carries=0):
num1, num2 = str(num1), str(num2)
# if num2 is smaller than num1,
# then reverse their assignments, and apply left-padding
# to the smaller number.
if int(num2) < int(num1):
num1, num2 = num2.zfill(len(num1)), num1
else:
num1, num2 = num1.zfill(len(num2)), num2
carries_list = [0]
new_answer = ''
for i in range(len(num2)):
dig_mul = str(int(num1[-1])*int(num2[len(num2) - i - 1]) + carries_list[i])
if i < len(num2) - 1:
new_answer = dig_mul[-1] + new_answer
carries_list.append(int(dig_mul[:-1].zfill(1)))
else:
new_answer = dig_mul + new_answer
new_answer += '0'*(len(num2)-len(str(int(num1))))
carries_list = [car for car in carries_list if car != 0]
if len(str(int(num1))) == 1:
# If this is the last digit in num1,
# then return the sum of the answer of the previous operation
# and the answer of the current operation, counting
# the addition carries in the process.
# Return the final answer as well as the count
# of multiplication and addition carries.
return count_addition_carries_rec([int(answer), int(new_answer)],
answer=0,
carries=carries+len(carries_list))
else:
# If there are more digits in num1, repeat the operation
# with num1 stripped of its last digit.
return count_multiplication_carries_rec(num1[:-1],
num2,
*count_addition_carries_rec([int(answer), int(new_answer)],
answer=0,
carries=carries+len(carries_list)))
count_multiplication_carries_rec
不像添加方法那样通用,但可以轻松修复。您可以创建一个辅助方法,一次调用count_multiplication_carries_rec
两个数字,或者您可以修改当前实现以使用任意数量的整数。
使用2种方法的例子:
>>> count_addition_carries_rec([99,99])
(198, 1)
>>> count_addition_carries_rec([17, 17, 17])
(51, 2)
>>> count_multiplication_carries_rec(15,15)
(225, 2)
>>> count_multiplication_carries_rec(657,34)
(223380, 6)
如您所见,这些方法返回加法/乘法运算的结果以及执行该运算时发生的进位数。