You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

字符串大数竖式乘法Python实现:加法阶段技术求助

解决字符串大数乘法的竖式对齐加法问题

我明白你想要严格模拟竖式乘法的流程,而不是依赖Python的大整数特性。你已经成功得到了每一位相乘的结果列表,现在卡在了移位对齐后逐位相加的环节,这就来帮你解决这个问题。

首先,先明确我们的目标:对于list_to_add = [1638, 1404, 1170],这些数分别对应234*7234*6234*5的结果。在竖式里,234*6的结果要左移1位(补1个0),234*5的结果左移2位(补2个0),本质是让每个乘积的个位对齐到原乘数的对应数位上,然后从个位开始逐位相加处理进位。

修正后的完整代码(含竖式加法逻辑)

def mul(upper_no, lower_no):
    upper_len = len(upper_no)
    lower_len = len(lower_no)
    list_to_add = []
    
    # 第一步:计算每一位相乘的结果(字符串形式,方便后续处理)
    for lower_idx in range(lower_len - 1, -1, -1):
        carry = 0
        current_product_digits = []
        # 从高位到低位遍历被乘数,计算每一位乘积
        for upper_idx in range(upper_len - 1, -1, -1):
            num1 = int(upper_no[upper_idx])
            num2 = int(lower_no[lower_idx])
            total = num1 * num2 + carry
            current_product_digits.append(str(total % 10))
            carry = total // 10
        # 处理最后剩余的进位
        if carry != 0:
            current_product_digits.append(str(carry))
        # 反转得到正确的乘积字符串(因为我们是从个位开始存的)
        current_product = ''.join(reversed(current_product_digits))
        list_to_add.append(current_product)
    
    print(f"待对齐的乘积列表:{list_to_add}")
    
    # 第二步:模拟竖式对齐加法
    # 计算结果的最大可能长度:每个乘积的长度 + 移位位数(即它在list_to_add中的索引)
    max_result_length = max(len(num) + idx for idx, num in enumerate(list_to_add))
    # 初始化结果数组,每个位置存对应数位的数值,初始为0
    result_digits = [0] * max_result_length
    
    # 遍历每个乘积,将每一位对齐到正确的位置
    for shift_idx, num_str in enumerate(list_to_add):
        # 反转乘积字符串,方便从个位开始处理
        reversed_num = reversed(num_str)
        for digit_pos, char in enumerate(reversed_num):
            digit = int(char)
            # 当前数位在结果中的位置 = 移位位数 + 该数位在乘积中的位置(0是个位)
            result_pos = shift_idx + digit_pos
            result_digits[result_pos] += digit
    
    # 处理进位:从个位到高位依次计算
    carry = 0
    for pos in range(len(result_digits)):
        total = result_digits[pos] + carry
        result_digits[pos] = total % 10
        carry = total // 10
    
    # 如果最后还有未处理的进位,追加到结果末尾
    while carry > 0:
        result_digits.append(carry % 10)
        carry = carry // 10
    
    # 反转结果数组得到正确顺序,转成字符串并去除前导0
    final_result = ''.join(map(str, reversed(result_digits))).lstrip('0')
    # 处理全0的特殊情况(比如输入'0'和'0')
    if not final_result:
        final_result = '0'
    
    print(f"最终乘法结果:{final_result}")
    return final_result

# 测试你的示例
mul('234', '567')

关键逻辑解释

  1. 乘积计算优化
    我把原来的字符串拼接改成了列表存数位,最后反转得到正确的乘积字符串,这样处理进位更直观,避免了字符串拼接的繁琐。

  2. 对齐与累加

    • 每个乘积的移位位数等于它在list_to_add中的索引(第一个乘积对应乘数的个位,移位0位;第二个对应十位,移位1位,以此类推)。
    • 我们用一个数组result_digits来存结果的每一位,把每个乘积的每一位加到对应位置上,比如1404的个位4,要加到结果的第1位(因为移位1位)。
  3. 进位处理
    从个位开始,逐位计算总和加上进位,保留当前位的余数,更新进位值,最后如果还有剩余进位,直接追加到结果末尾。

  4. 结果格式化
    反转结果数组得到正确的高位到低位顺序,去除前导0,同时处理输入全0的特殊情况。

运行这段代码,输入mul('234','567')会输出最终结果132678,完全符合竖式乘法的计算流程。

内容的提问来源于stack exchange,提问作者Mahesh

火山引擎 最新活动