Целочисленная система base-x с использованием рекурсии в python

Я пытаюсь написать рекурсивный код, который может преобразовать число в любую базовую систему. например, целое число 10 в двоичном виде будет преобразовано в 1010

Пока у меня есть это, но у меня есть "Нет" между моими результатами. Может ли кто-нибудь помочь мне с моим кодом?

def convert(a,b):
    add = a%b
    if a<=1:
        return a
    else:
        print(base(a//b,b), add)

моя идея состоит в том, что%b - это число, которое нужно добавить в конец числа, а a//b - это рекурсивная часть, где он использует ответ предыдущего двоичного числа, поэтому 10 в базе 2 просто конвертируется (5,2) и добавить 0 в конце, так как a//b=5 и a%b=0, что = 1010

5 ответов

Я рекомендую вам структурировать ваш код более точно. Вы можете разбить неопределенно определенную задачу, о которой вы упомянули, на различные подзадачи, например:

  • определить и нормализовать знаки числа и основания (вам нужно поддерживать отрицательные основания или вы можете просто вызвать исключение?), а также обеспечить немедленное исключение в случаях ошибок (например, основание0 или же 1);
  • написать функцию, которая (дать положительные и правильные значения для a а также b) возвращает "последовательность цифр" для представления a в базе bгде "цифра" - это целое число между 0 включены и b не входит;
  • написать функцию, которая при наличии расширений знака и последовательности цифр a строит и возвращает строковое представление - зависит от того, как вы хотите представить очень большие "цифры", когда b большое, скажем> 36, если вы хотите использовать цифры, тогда Буквы ASCII, для первых 36 цифр очевидным образом; возможно, вам следует принять строку "алфавит", чтобы использовать ее для этой цели (и первая функция выше должна вызвать исключение, когда b слишком велико для данного алфавита)
  • написать функцию, которая использует все вышеперечисленные для вывода строки

Из этих задач только вторая может рассматриваться как подходящая для "рекурсивной" реализации, если кто-то настаивает (хотя итеративная реализация на самом деле намного более естественна!) - учитывая, что это домашняя работа, я думаю, вам придется делайте это рекурсивно, потому что это часть поставленной задачи, ну что ж!-). Но, для справки, один очевидный способ итерации был бы:

  def digitsequence(a, b):
    results = []
    while True:
      results.append(a % b)
      if a < b: break
      a //= b
    return reversed(results)

предполагая, что кто-то хочет, чтобы последовательность цифр была в порядке "большого порядкового номера", к которому мы привыкли, из того, как позиционная десятичная запись вошла в западную культуру (это был более естественно вычисляемый порядок с прямым порядком байтов в арабском оригинале... но арабский пишется справа налево буквальная транскрипция этого порядка на европейских языках, написанная слева направо, стала big-endian!-).

В любом случае, вы можете принять простую линейную рекурсию как способ неявного "обращения" вещей (вы могли бы сказать, что такая рекурсия "скрывает" стек "последний вошел, первый вышел", что явно является способом обратить последовательность;-), я предполагаю, что откуда может исходить спецификация рекурсии в домашнем задании;-).

Я работаю над созданием пакета для этого.

Я рекомендую вам использовать мой Base.py https://github.com/kamijoutouma/bases.py который был вдохновлен Base.js

from bases import Bases
bases = Bases()

bases.toBase16(200)                // => 'c8'
bases.toBase(200, 16)              // => 'c8'
bases.toBase62(99999)              // => 'q0T'
bases.toBase(200, 62)              // => 'q0T'
bases.toAlphabet(300, 'aAbBcC')    // => 'Abba'

bases.fromBase16('c8')               // => 200
bases.fromBase('c8', 16)             // => 200
bases.fromBase62('q0T')              // => 99999
bases.fromBase('q0T', 62)            // => 99999
bases.fromAlphabet('Abba', 'aAbBcC') // => 300

обратитесь к https://github.com/kamijoutouma/bases.py, чтобы узнать, какие базы можно использовать

Для вашего конкретного вопроса

Если вы хотите перейти на двоичный код и обратно, вы можете сделать

>>> from bases import Bases
>>> bases = Bases()
>>> bases.toBase(200,2)
'11001000'
>>> bases.fromBase('11001000',2)
200
>>> bases.toBase2(200)
'11001000'
>>> bases.fromBase2('11001000')
200

Повеселись!!!

И снова список используемых баз с этой библиотекой можно найти по https://github.com/kamijoutouma/bases.py.

У вас нет оператора возврата в вашем блоке else, и у вас нет рекурсивного вызова convert,

Я думаю, что вы хотите:

if a<=1:
    return str(a)
else:
    return str(convert(a//b,b)) + str(add)

как в

>>> def convert(a,b):
...   add = a%b
...   if a<=1:
...     return str(a)
...   else:
...     return str(convert(a//b,b)) + str(add)
... 
>>> convert(10,2)
'1010'

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

Простое рекурсивное решение (с ограничениями) и код для его проверки:

from string import hexdigits

def convert(a, b):

    return '0' if a == 0 else convert(a // b, b).lstrip('0') + hexdigits[a % b]

if __name__ == '__main__':

    # Test code

    from random import randint

    for _ in range(10):
        number = randint(0, 1000)
        base = randint(2, 16)

        conversion = convert(number, base)

        print(number, "base", base, "->", conversion, "->", int(conversion, base), "base", base)

Ограничения включают отсутствие поддержки отрицательных чисел; в настоящее время ограничено основаниями в диапазоне 2 - 16; не проверяет на недопустимые аргументы.

ТЕСТОВЫЙ ЗАБЕГ

% python3 test.py
127 base 3 -> 11201 -> 127 base 3
666 base 3 -> 220200 -> 666 base 3
348 base 2 -> 101011100 -> 348 base 2
139 base 10 -> 139 -> 139 base 10
464 base 7 -> 1232 -> 464 base 7
330 base 11 -> 280 -> 330 base 11
633 base 10 -> 633 -> 633 base 10
789 base 4 -> 30111 -> 789 base 4
355 base 15 -> 18a -> 355 base 15
582 base 8 -> 1106 -> 582 base 8
%

convert функция возвращает None, и print печатает это. Вы должны либо удалить print вызвать или накапливать результат в виде строки и возвращать его.

(Я предполагаю, что звонок base на самом деле предназначен для рекурсивного вызова convert.)

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