18

数字に対応する一連の文字、つまり「A」、「DE」、「GJE」などを生成したいと思います。最初の 26 はとても簡単なので、3 は "C" を返し、26 は "Z" を返し、27 は "AA" を返し、28 は "AB" を返します。

私がよく理解できないのは、これを行う方法です。これにより、渡された任意の数値が処理されます。したがって、4123 を渡すと、(26 * 26 * 26) は最大+17,000 の組み合わせ。

助言がありますか?

4

9 に答える 9

18
class Numeric
  Alph = ("a".."z").to_a
  def alph
    s, q = "", self
    (q, r = (q - 1).divmod(26)); s.prepend(Alph[r]) until q.zero?
    s
  end
end

3.alph
# => "c"
26.alph
# => "z"
27.alph
# => "aa"
4123.alph
# => "fbo"
于 2013-01-31T18:50:40.967 に答える
16

Ruby 2.0の@sawaの元の回答を微調整しました。これは、彼をそのまま機能させることができなかったためです。

class Numeric
  Alpha26 = ("a".."z").to_a
  def to_s26
    return "" if self < 1
    s, q = "", self
    loop do
      q, r = (q - 1).divmod(26)
      s.prepend(Alpha26[r]) 
      break if q.zero?
    end
    s
  end
end

そして、ここでは文字列から整数に逆になっています:

class String
  Alpha26 = ("a".."z").to_a

  def to_i26
    result = 0
    downcased = downcase
    (1..length).each do |i|
      char = downcased[-i]
      result += 26**(i-1) * (Alpha26.index(char) + 1)
    end
    result
  end

end

使用法:

1234567890.to_s26 
# => "cywoqvj"

"cywoqvj".to_i26  
# => 1234567890

1234567890.to_s26.to_i26
# => 1234567890

"".to_i26
# => 0

0.to_s26
# => ""
于 2015-01-17T04:30:40.637 に答える
7

文字列にはsuccメソッドがあるため、範囲内で使用できます。「Z」の後継はたまたま「AA」なので、これは機能します。

h = {}
('A'..'ZZZ').each_with_index{|w, i| h[i+1] = w } 
p h[27] #=> "AA"
于 2013-01-31T19:44:52.000 に答える
4

https://stackoverflow.com/a/17785576/514483からのこの回答が気に入りました

number.to_s(26).tr("0123456789abcdefghijklmnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
于 2016-05-18T13:21:49.050 に答える
2
def letter_sequence(n)
    n.to_s(26).each_char.map {|i| ('A'..'Z').to_a[i.to_i(26)]}.join
end
于 2015-07-01T04:54:56.753 に答える
2

ここにある基数変換方法を使用します。また、この番号付けシステムにある「0」がないために変更しました。最終的なケースが対処されました。

def baseAZ(num)
  # temp variable for converting base
  temp = num

  # the base 26 (az) number
  az = ''

  while temp > 0

    # get the remainder and convert to a letter
    num26 = temp % 26
    temp /= 26

    # offset for lack of "0"
    temp -= 1 if num26 == 0

    az = (num26).to_s(26).tr('0-9a-p', 'ZA-Y') + az
  end

  return az
end

I/O:

>> baseAZ(1)
=> "A"
>> baseAZ(26^2 + 1)
=> "Y"
>> baseAZ(26*26 + 1)
=> "ZA"
>> baseAZ(26*26*26 + 1)
=> "YZA"
>> baseAZ(26*26*26 + 26*26 + 1)
=> "ZZA"
于 2013-01-31T19:26:56.577 に答える
0

澤の答えに基づいて、再帰的ではありますが、独立して機能し、望ましい結果を達成する方法が必要でした。

def num_to_col(num)
  raise("invalid value #{num} for num") unless num > 0
  result, remainder = num.divmod(26)
  if remainder == 0
    result -= 1
    remainder = 26
  end
  final_letter = ('a'..'z').to_a[remainder-1]
  result > 0 ? previous_letters = num_to_col(result) : previous_letters = ''
  "#{previous_letters}#{final_letter}".upcase
end
于 2014-09-23T10:46:49.923 に答える