【问题标题】:Sum of Strings as Numbers字符串总和作为数字
【发布时间】:2023-01-08 00:04:27
【问题描述】:

我正在尝试解决来自 Codewars 的 this 练习。

描述:

给定两个整数的字符串表示形式,返回这些整数之和的字符串表示形式。 例如:sumStrings('1','2') // => '3' 除了十个数字“0”到“9”之外,整数的字符串表示将不包含任何字符。 我已经删除了 BigInteger 和 BigDecimal 在 java 中的使用 Python:您的解决方案需要处理大量数字(大约一百万位数),转换为 int 将不起作用。

在 Python 中,我所有的测试用例都正常,但执行超时仍然出现。有什么提示可以让它工作吗?我还可以采用什么其他方法? 我当前的代码在下面。 非常感谢任何帮助!

def sum_strings(x, y):
      
    if x == '' and y == '':
        return '0'
    
    if x == '0' and y == '0':
        return '0'
    
    if x == '' and y == '0' or x == '0' and y == '':
        return '0'
    
    listaX = list(x)
    listaY = list(y)

    if len(listaX) - len(listaY) > 0:       
        while len(listaY) < len(listaX):
            listaY.insert(0, '0')
    if len(listaY) - len(listaX) > 0:       
        while len(listaY) > len(listaX):
            listaX.insert(0, '0')

    for i in range(0, len(listaX)):        
        listaX[i] = int(listaX[i])
        listaY[i] = int(listaY[i])

    listaSomas = []
    quociente = 0

    for i in range(len(listaX) - 1, -1, -1):
        soma = listaX[i] + listaY[i] + quociente
        if soma > 9 and i > 0:
            quociente = soma // 10
            listaSomas.insert(0, soma % 10)
        elif soma > 9 and i == 0:
            quociente = soma // 10
            listaSomas.insert(0, soma % 10)
            listaSomas.insert(0, quociente)
        elif soma <= 9:
            listaSomas.insert(0, soma)
            quociente = 0
            
    if listaSomas[0] == 0:                  
        listaSomas.remove(listaSomas[0])
            
    for i in range(0, len(listaSomas)):
        listaSomas[i] = str(listaSomas[i])
    listaSomas = ''.join(listaSomas)
    
    return listaSomas

#MAIN
print(sum_strings('123', '456'))

【问题讨论】:

  • 复制到不同的容器。在前面插入,转换为不同的类型。这些可能是对一个非常大的字符串进行的昂贵操作。您可以使用 reversed 来获取迭代器,将它们与 itertools.zip_longest(fillvalue='0') 结合使用以对单个数字进行基本算术运算,然后再次将其反转以进行输出吗?

标签: python string algorithm


【解决方案1】:

我试了一下,我不确定 kata 界面是否正常运行。由于(下面的)代码测试正常,并且确实在 12 秒(12,000 毫秒)之前返回

def clean_int(v):
    if len(v) == 0:
        return 0 
    return int(v) 

def sum_strings(x, y):
    ci = clean_int
    return f'{ci(x) + ci(y)}'

这足够快,因为我可以在 12 秒之前运行超过 800k。 - 型应用程序似乎出现故障,除非他们期望有一些模糊的加速。

【讨论】:

    【解决方案2】:

    我看到了那个链接,上面清楚地写着:Python:您的解决方案需要处理大量数字(大约一百万位数字),转换为 int 将不起作用。

    我能想到的一些改进是:

    a)不要为每个数字插入和删除。只需附加到结果列表即可。

    b) 在处理字符串之前不需要附加 0。

    一种正确编码的快速方法,这得到了公认:

    def sum_strings(x, y):
        i = len(x)
        j = len(y)
        c = 0
        out = []
        while i > 0 and j > 0:
            s = int(x[i-1]) + int(y[j-1]) + c
            if s >= 10:
                c = s // 10
                s = s % 10
            else:
                c = 0
            out.append(s)
            i -= 1
            j -= 1
        
        
        while i > 0:
            s = int(x[i-1]) + c
            if s >= 10:
                c = s // 10
                s = s % 10
            else:
                c = 0
            out.append(s)
            i -= 1
        
           
        while j > 0:
            s = int(y[j-1]) + c
            if s >= 10:
                c = s // 10
                s = s % 10
            else:
                c = 0
            out.append(s)
            j -= 1
        
        
        if c > 0:
            out.append(c)
            
        out = ''.join([str(n) for n in reversed(out)]).lstrip("0")
        
        if out:
            return out
            
        return "0"
    

    【讨论】:

    • 从逻辑上讲,OP 的方法是相同的。这无助于找出为什么他的提交不起作用。
    • @AbhinavMathur OP 的代码正在执行我在答案中提到的不必要的操作,这解释了为什么它没有被接受。
    【解决方案3】:

    一个循环就足够了,以便将两个数字的每个数字相加:

    def sum_strings(x, y):
        # remove whitespaces from x and y
        x,y = map(str.strip, (x,y))
    
        # skip useless inputs
        if (x == '0' and y =='0') or (x == '' and y == ''):
            return "0"
        
        # determine max string, so we could fill the smaller one with leading 0s
        maxLen = max(len(x), len(y))
    
        # pad both numbers with 0s and reverse them, so we can sum the digits up
        x = x.zfill(maxLen)[::-1]
        y = y.zfill(maxLen)[::-1]
    
        r = []
        carryover = 0
    
        # sum both digits and keep the carryover!
        for i  in range(maxLen):
            carryover, res = str(int(x[i]) + int(y[i]) + int(carryover)).zfill(2)
            r.append(res)
            # add the carryover for the last digit as is!
            if i == maxLen-1:
                r.append(carryover)
        r = "".join(r)[::-1].lstrip("0")
        return r if r else "0"
    

    出去:

    print(sum_strings('19', '12'))
    >> 31
    

    【讨论】:

      猜你喜欢
      • 2012-08-11
      • 2013-01-11
      • 1970-01-01
      • 2019-03-29
      • 1970-01-01
      • 2014-03-28
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多