字符串相乘(大数相乘) python实现

本文详细介绍了一种在Python中处理大数乘法的方法,通过字符串形式表示的非负整数进行乘法运算,避免了标准库大数类型或直接转换为整数的限制。文章提供了两种解题思路,一种采用数组存储,另一种采用链表存储,对比了两者在时间复杂度上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先讲解 两个小技巧

list 反转 reverse

>>> l=[1,2,3,4,5,6]
>>> l.reverse()
>>> l
[6, 5, 4, 3, 2, 1]

str 反转 [::-1]

>>> 
>>> s="abcde"
>>> r_s=s[::-1]
>>> r_s
'edcba'
>>> 

题目描述

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = “2”, num2 = “3”
输出: “6”
示例 2:

输入: num1 = “123”, num2 = “456”
输出: “56088”
说明:

num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

解答

需要知道

两个数相乘,其乘积结果的位数 小于等于 两个数长度之和
例如:
12345 * 6789 乘积结果的 位数不超过9(5+4)

思路

思路很简单 ,代码完全模拟我们的思维方式 请在纸上算 123X456 同时结合着代码 multiply_best 一步一步来看
千万要静下心看!!!

我这里实现了两种解题思路
这里感慨一下:两个算法采用的思想是一样的,但是时间复杂度确实差距很大,区别就在 一个采用了数组存储(操作简单),一个采用链表存储(操作复杂)

class ListNode:
    def __init__(self,value):
        self.value=value
        self.exp=None
        self.next=None


class Solution:
    @staticmethod
    def multiply_best(num1, num2):
        """
        采用数组存储
        :type num1: str
        :type num2: str
        :rtype: str
        """
        if num1=="0" or num2=="0":
            return "0"
        res=[0]*(len(num1)+len(num2))
        len_num1 = len(num1)
        len_num2 = len(num2)
        for i in range(len_num1-1,-1,-1):
            num_1 = int(num1[i])
            exp_1= len_num1-i-1
            for j in range(len_num2 - 1, -1, -1):
                num_2 = int(num2[j])
                exp_2 = len_num2 - j - 1
                exp=exp_1+exp_2
                res[exp]+=num_1*num_2
                c=res[exp]//10
                res[exp]=res[exp] % 10
                exp+=1
                while c>0:
                    res[exp] += c
                    c = res[exp] // 10
                    res[exp] = res[exp] % 10
                    exp = exp + 1
        flag = False
        if res[-1]==0:
            flag = True


        res_str=""
        for i in range(len(res)-1,-1,-1):
            if res[i]==0 and flag:
                flag=False
                continue
            else:
                res_str+=str(res[i])
        return res_str




    @staticmethod
    def multiply_worse(num1, num2):
        """
        采用链表存储
        :type num1: str
        :type num2: str
        :rtype: str
        """
        if num1=="0" or num2=="0":
            return 0



        p_head_num1=ListNode(-1)
        p_head_num2 = ListNode(-1)
        res_head=ListNode(-1)


        len_num1=len(num1)
        len_num2=len(num2)

        for index,num in enumerate(num1):
            p = ListNode(int(num))
            p.exp = len_num1-index-1
            p.next=p_head_num1.next
            p_head_num1.next=p

        for index,num in enumerate(num2):
            p = ListNode(int(num))
            p.exp = len_num2-index-1
            p.next=p_head_num2.next
            p_head_num2.next=p


        p2=p_head_num2.next
        while p2 is not None:
            p1 = p_head_num1.next
            while p1 is not None:
                tmp = p2.value*p1.value
                c = tmp // 10
                value = tmp % 10
                exp = p2.exp+p1.exp
                p = res_head.next
                q=res_head
                flag_1 = True
                flag_2 = True
                while p is not None:
                    if p.exp==exp:
                        c += (p.value + value)//10
                        p.value=(p.value+value)%10
                        flag_1=False
                        q = p
                        p = p.next
                        if c == 0:
                            flag_2=False
                        break
                    q=p
                    p=p.next
                if flag_1:
                    p_new=ListNode(value)
                    p_new.exp=exp
                    q.next=p_new
                    q=q.next
                if c >0 and flag_2 :
                    while c != 0 and p is not None:
                        y=p.value + c
                        p.value = y % 10
                        c = y//10
                        exp=exp+1
                        q=p
                        p=p.next
                    if c>0:
                        p_new = ListNode(c)
                        p_new.exp = exp + 1
                        q.next = p_new


                p1=p1.next
            p2=p2.next
        p=res_head.next
        res=""
        while p is not None:
            res=str(p.value)+res
            p=p.next
        return res





if __name__=="__main__":
    num1="999"
    num2="999"
    print(Solution.multiply_best(num1,num2))
<think>好的,用户想了解Python字符串相乘的操作或行为。首先,我需要回忆Python中的字符串相乘是什么样子的。通常来说,字符串相乘指的是用乘法运算符*来重复字符串多次,比如"abc" * 3会得到"abcabcabc"。但用户提供的引用内容似乎涉及的是大数相乘,也就是两个表示数字字符串相乘,比如"123" * "456",得到另一个字符串表示的乘积。这可能让用户产生困惑,因为Python本身并不直接支持用*运算符对两个字符串进行数值上的乘法,而是需要自己实现算法,比如大数相乘的处理。 接下来,我需要查看用户提供的三个引用。引用[1]给出了一个mul函数的代码,该函数将两个字符串数字反转,逐位相乘并处理进位,最后得到结果的字符串。引用[2]提到了一个add_result的字典,可能用于处理相加时的进位。引用[3]则讨论了当两个数取最小值时的乘积长度,说明乘积的位数范围。这说明用户的问题其实更偏向于如何实现两个字符串表示的整数的乘法,而不是Python内置的字符串重复操作。 因此,用户可能误解了“字符串相乘”的概念,或者想了解如何实现类似大数相乘的功能。需要明确区分Python的原生字符串相乘(重复)和用户引用的字符串相乘大数计算)。在回答中,首先要解释这两种不同的情况,然后详细说明如何实现大数相乘的算法,参考用户提供的代码和引用内容。同时,需要确保回答结构清晰,分步骤解释,并引用相关引用内容来支持说明。 可能还需要指出,虽然Python本身支持整数运算,但如果是处理字符串形式的数字而不转换为整数,就需要手动实现逐位相乘和进位处理,如引用中的代码所示。此外,引用[3]提到的乘积位数范围可以帮助优化结果的处理,比如预先分配结果数组的长度。 最后,生成相关问题时要围绕这两个方面:原生字符串相乘的行为和大数相乘实现方法,以及可能的优化和应用场景。</think>### Python字符串相乘操作详解 Python中"字符串相乘"存在两种不同场景的语义理解,需要根据上下文区分操作行为: 一、原生字符串乘法运算(单操作数) $$ str * n \quad (n \in \mathbb{N}) $$ ```python print("abc" * 3) # 输出:abcabcabc print("-" * 20) # 输出:-------------------- ``` 特性说明: 1. 乘法运算符只能连接正整数 2. 结果生成重复拼接的字符串 3. 时间复杂度为$O(n)$,n为重复次数 二、大数相乘运算(双操作数) 当处理超长数字字符串时(超过整型存储范围),需实现特殊算法[^1]: $$ \text{num1} = "225",\ \text{num2} = "225" \Rightarrow \text{result} = "50625" $$ 实现步骤解析(引用代码说明): 1. **预处理零值** ```python if num1=="0" or num2=="0": return "0" # 快速返回零值情况[^1] ``` 2. **反转字符串** ```python num1 = num1[::-1] # 低位对齐便于计算[^1] num2 = num2[::-1] ``` 3. **创建结果数组** ```python len_all = len(num1)+len(num2) # 确定最位数[^3] result = [0 for i in range(len_all)] ``` 4. **逐位相乘累加** ```python for i in range(len(num1)): for j in range(len(num2)): result[i+j] += int(num1[i])*int(num2[j]) # 模拟竖式计算[^1] ``` 5. **处理进位** ```python for i in range(len_all): if result[i] > 9: result[i+1] += result[i] // 10 # 进位传递[^2] result[i] = result[i] % 10 ``` 6. **结果格式化** ```python result.reverse() res = str(int("".join(map(str, result)))) # 去除前导零 ``` 性能特征: - 时间复杂度:$O(mn)$,其中m,n为输入字符串长度 - 空间复杂度:$O(m+n)$,用于存储中间结果 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值