怎么算数乘?

时间:2015-03-14 23:53:35

标签: python

我在使用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)

2 个答案:

答案 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)

如您所见,这些方法返回加法/乘法运算的结果以及执行该运算时发生的进位数。