43. 字符串相乘

总结:
	两个的思路都也算比较好想吧,重点是在演草纸上先试着看一看
	fun2的时间复杂度更高,代码的实现难度也更高
	fun3的时间复杂度低一些,代码也相对更简单,就是思路更不好想一些

fun2的写法是官方的写法一,所以能通过不是没有原因的



def fun1(num1,num2):#这个思路有问题,注意是乘法,需要和每个数相乘



    #1.创建carry(进位),和存储结果的str_
    carry=0
    str_=''
    #2.将num1,num2同时从后往前遍历,进行乘积,进位,和字符串拼接
    ind=-1
    while ind>=-len(num1) and ind>=-len(num2):#这里需要加个等于
        cur=eval(num1[ind])*eval(num2[ind])+carry
        str_=cur%10+str_ #拼接
        carry=cur//10  #进位
        ind-=1

    #3.可能出现长度不一致问题,所以再将num1,num2<<分别>>遍历

    #4.看进位是否为0

    #5.返回


def fun2(num1,num2):
    if num1 == '0' or num2 == '0':
        return "0"
    nums = []  # 存储结果
    pinjie = ""  # 填充0
    ind1 = -1
    while ind1 >= -len(num2):
        cur = eval(num2[ind1])  # 当前数
        carry = 0  # 进位
        str_ = ''  # 结果存储
        ind2 = -1

        while ind2 >= -len(num1):
            item = cur * eval(num1[ind2]) + carry  # 这里其实可以化简,因为num1会用很多遍
            str_ = str(item % 10) + str_  # 拼接
            carry = item // 10  # 进位
            ind2 -= 1
        # 遍历结束,填充0
        if carry != 0:
            str_ = str(carry) + str_
        str_ = str_ + pinjie
        pinjie += "0"
        nums.append(str_)
        ind1 -= 1

    # 最长的肯定是最后一位
    # 开始归为一类
    sum_ = ""
    carry = 0  # 进位
    for xunhuan in range(-1, -len(nums[-1]) - 1, -1):  # 最大循环次数
        qiuhe = 0
        for i in range(len(nums)):
            if abs(xunhuan) <= len(nums[i]):
                # 后面就是直接往上面加就好了
                qiuhe += eval(nums[i][xunhuan])
        qiuhe = qiuhe + carry
        sum_ = str(qiuhe % 10) + sum_
        carry = qiuhe // 10
    if carry != 0:
        sum_ = str(carry) + sum_
    return sum_

这个是省去了后面的所有数求和的问题
减少了o(n平方)的时间复杂度

def fun3(num1,num2):
    '''
        怎么说呢,我只能说写的不怎么样
        不过居然是官方解法,也是醉了...
        上面的代码在最后求和中浪费了大量的时间,所以我应该怎么办才可以避免求和呢?


        基本思路(拿一个数组,因为一直在变化),开辟合适的空间
            然后进行乘积运算,不进行进位直接放在数组中
            等待运算结束,在进行进位
            最后拼接在一起

        我需要创建一个数组(nums存放,那么我怎么确定他的长度?是append或者insert添加不可能吧)
        看一下两个数相乘的最短长度
        num1长度为m,num2长度为n 这样一个是 10**(m-1)一个是10**(n-1)
            那么合起来就是10**(n+m-2)对应就是n+m-1长度
        num1长度为m,num2长度为n 这样就是 10**(m)-1 和 10**(n)-1
            这样两个相乘 10**(m+n)-10**(m)-10**(n)+1长度一定是小于m+n+1
        这样将nums的长度开到n+m一定是没问题.
    :param num1:
    :param num2:
    :return:
    '''
    if num1 == '0' or num2 == '0':
        return "0"
    m = len(num1)
    n = len(num2)
    nums = [0] * (m + n)
    for i in range(-1, -n - 1, -1):
        cur_ = eval(num2[i])
        for j in range(-1, -m - 1, -1):
            nums[i + j + 1] += cur_ * eval(num1[j])
    # 开始进位
    for i in range(-1, -len(nums), -1):
        cur = nums[i]
        nums[i] = str(cur % 10)
        nums[i - 1] += cur // 10
    if nums[0] == 0:
        nums = nums[1::]
    else:
        nums[0] = str(nums[0])
    return ''.join(nums)



print(fun3("9","9"))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值