Получить число из массива цифр - PullRequest
0 голосов
/ 05 апреля 2019

Чтобы разбить число на цифры в заданной базе, Джулия имеет функцию digits():

julia> digits(36, base = 4)
3-element Array{Int64,1}:
 0
 1
 2

Что такое обратная операция? Если у вас есть массив цифр и основание, существует ли встроенный способ преобразования этого числа в число? Я мог бы напечатать массив в строку и использовать parse(), но это звучит неэффективно, и также не будет работать для базисов> 10.

Ответы [ 2 ]

3 голосов
/ 05 апреля 2019

Предыдущие ответы верны, но есть и вопрос эффективности:

sum([x[k]*base^(k-1) for k=1:length(x)])

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

sum(x[k]*base^(k-1) for k in 1:length(x))

Это также выделяет массив перед суммированием: sum(d.*4 .^(0:(length(d)-1)))

Если вы действительно хотите хорошую производительность, напишите цикл и избегайте повторного возведения в степень:

function undigit(d; base=10)
    s = zero(eltype(d))
    mult = one(eltype(d))
    for val in d
        s += val * mult
        mult *= base
    end
    return s
end

Это имеет еще одно ненужное умножение, вы можете попытаться найти способ пропустить это. Но производительность в 10-15 раз лучше, чем у других подходов в моих тестах, и имеет нулевое распределение.

Редактировать: На самом деле небольшой риск для обработки типов выше. Если входной вектор и base имеют разные целочисленные типы, вы можете получить нестабильность типа. Этот код должен вести себя лучше:

function undigits(d; base=10)
    (s, b) = promote(zero(eltype(d)), base)
    mult = one(s)
    for val in d
        s += val * mult
        mult *= b
    end
    return s
end
2 голосов
/ 05 апреля 2019

Ответ, кажется, написан непосредственно в документации digits:


help?> digits
search: digits digits! ndigits isdigit isxdigit disable_sigint

  digits([T<:Integer], n::Integer; base::T = 10, pad::Integer = 1)

  Return an array with element type T (default Int) of the digits of n in the given base,
  optionally padded with zeros to a specified size. More significant digits are at higher
  indices, such that n == sum([digits[k]*base^(k-1) for k=1:length(digits)]).

Так что для вашего случая это будет работать:

julia> d = digits(36, base = 4);

julia> sum([d[k]*4^(k-1) for k=1:length(d)])
36

А приведенный выше код можно сократить с помощью оператора точки:

julia> sum(d.*4 .^(0:(length(d)-1)))
36
...