Каков самый быстрый способ суммировать две строки, состоящие только из чисел, но без предварительного преобразования каждой из них в int?

Если мне даны две строки, состоящие только из чисел 0-9, как быстрее всего их суммировать? Делать что-то вроде str(int(num1) + int(num2)) не разрешено и не получится.

В неудачном тесте упоминается, что максимум для int() составляет 4300 символов:

ValueError: Exceeds the limit (4300) for integer string conversion: value has 2102288 digits; use sys.set_int_max_str_digits() to increase the limit

Каждая из двух строк чисел может иметь длину более 1 000 000 символов/цифр, быть пустой строкой, иметь несовпадающую длину и/или содержать начальные нули.

Единственный способ, который я могу придумать, - это добавлять каждую верхнюю / нижнюю цифру по одной справа налево и при необходимости переносить 1.

Моя версия проходит все тесты, но не работает на длинных числах.

def sum_strings(x, y):
    if not x:
        x = '0'
    if not y:
        y = '0'
    x_len = len(x)
    y_len = len(y)

    if x_len > y_len:
        y = y.rjust(x_len, '0')
    elif y_len > x_len:
        x = x.rjust(y_len, '0')

    carry = 0
    total = ''
    for index in range(len(x) - 1, -1, -1):
        new_sum = int(x[index]) + int(y[index]) + carry
        if new_sum > 9:
            new_sum -= 10
            carry = 1
        else:
            carry = 0
        total = f'{new_sum}{total}'

    answer = f'{carry}{total}' if carry else total
    return answer if len(answer) > 1 else answer.lstrip('0')

Время вышло:

Вот примеры «простых» тестов.

@test.describe('Basic tests')
def test_examples():

    @test.it('Example tests')
    def basic_tests():
        test.assert_equals(sum_strings("1", "1"), "2")
        test.assert_equals(sum_strings("123", "456"), "579")

Есть ли способ сделать это быстрее?

Обновлено: Вот обновленная/рабочая версия, хотя теперь, когда я вижу другие материалы, я думаю, что есть более чистые способы сделать это, чем этот:

def sum_strings(x, y):
    if not x:
        x = '0'
    if not y:
        y = '0'
    x_len = len(x)
    y_len = len(y)

    if x_len > y_len:
        y = y.rjust(x_len, '0')
    elif y_len > x_len:
        x = x.rjust(y_len, '0')

    carry = 0
    total = []
    for index in range(len(x) - 1, -1, -1):
        new_sum = int(x[index]) + int(y[index]) + carry
        if new_sum > 9:
            new_sum -= 10
            carry = 1
        else:
            carry = 0
        total.append(str(new_sum))

    if carry:
        total.append(str(carry))
    total_str = ''.join(reversed(total))
    return total_str[1:] if len(total_str) > 1 and total_str[0] == '0' else total_str

Я почти уверен, что уже видел этот вопрос (хотя я не помню идентификатор пользователя). Поскольку вы новый пользователь, я чувствую, что должен предупредить вас, что удаление вопросов, за которые вы проголосовали против, может привести к автоматическому бану алгоритмом SO. Если это вы, вам следует отредактировать вопросы, за которые проголосовали против, и закрытые вопросы, чтобы улучшить их. Пожалуйста, прочитайте эту запись часто задаваемых вопросов.

Amadan 17.02.2023 05:43

Да, предыдущий вопрос был закрыт до того, как я успел его отредактировать. Я сделал репост с более четким заголовком, так как я определенно испортил предыдущий заголовок. Я также добавил дополнительную информацию о тестовых примерах.

JeffSpicoli 17.02.2023 05:46

Улучшенные вопросы могут быть повторно открыты. Удаленные вопросы заморожены во времени, ожидая, пока SO выяснит, что от вас больше проблем, чем вы того стоите, и навсегда запретит вам (или близко к этому) задавать какие-либо вопросы. (Я не думаю, что это произойдет из-за одного этого случая, но лучше предупредить вас заранее.)

Amadan 17.02.2023 05:48

Чтобы объединить символы в строку, используйте оператор «+», а не «f'...'».

Graffito 17.02.2023 10:54

@Amadan хорошо, хорошо знать на будущее..

JeffSpicoli 17.02.2023 14:33

Строки неизменяемы в python, вы все время копируете «всего» (это делает его O (n ^ 2)), вам нужно что-то вроде построителя строк для создания результата. Извините, я недостаточно знаю python.

maraca 17.02.2023 23:49

Вау, не знал, что у int есть ограничение по длине. Интересно, почему это так?

Mark Ransom 17.02.2023 23:49

Не нужно делать это по одной цифре за раз, вы можете сделать 4299 цифр за раз.

Mark Ransom 17.02.2023 23:52

@mark: размер int не ограничен. Существует ограничение на длину десятичного преобразования между строкой и целым числом. Это было введено, чтобы избежать DOS-атак на серверы. Сообщение об ошибке сообщает вам, как изменить ограничение, как и документы Python.

rici 18.02.2023 05:53

См. docs.python.org/3/library/…

rici 18.02.2023 05:59

@rici да, извините, я должен был дать понять, что говорю о функции int(), а не о типе int. В прошлом я делал миллионные целые числа для тестирования.

Mark Ransom 18.02.2023 14:12

@mark: ты все еще можешь. Вам просто нужно использовать шестнадцатеричный (или восьмеричный).

rici 18.02.2023 14:22
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
1
12
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Создайте список цифр в том порядке, в котором вы их генерируете, а затем создайте окончательную строку, используя ''.join(reversed(digits)).

Хорошо, использование списка звучит как хорошая идея ... сегодня вечером постараюсь отметить этот ответ, если я получу его, используя список

JeffSpicoli 17.02.2023 22:45

Да, это сработало ... Он показывает ответы, которые представили другие, теперь, когда я решил проблему, и многие из них намного лучше, чем мое решение ... но, по крайней мере, он прошел все.

JeffSpicoli 19.02.2023 00:58

Другие вопросы по теме