使用ruby生成用来表示数字的字母?

我想生成一系列字母,即“A”,“DE”“GJE”等,对应一个数字。 前26个很容易,因此3返回“C”,26返回“Z”,27返回“AA”,28“AB”,依此类推。

我无法弄清楚的是如何做到这一点,所以它将处理传入的任何数字。所以如果我传入4123我应该回到3个字母的组合,因为(26 * 26 * 26)允许最多+17,000种组合。

有什么建议?

 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" 

对@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 downcase! (1..length).each do |i| char = self[-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 # => "" 

字符串确实有一个succ方法,因此它们可以在Range中使用。 “Z”的后继者恰好是“AA”,所以这有效:

 h = {} ('A'..'ZZZ').each_with_index{|w, i| h[i+1] = w } ph[27] #=> "AA" 

我喜欢这个答案: https : //stackoverflow.com/a/17785576/514483

 number.to_s(26).tr("0123456789abcdefghijklmnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ") 

使用此处找到的基本转换方法。 我也改变了它,因为我们在这个编号系统中缺少“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 

irb 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" 
 def letter_sequence(n) n.to_s(26).each_char.map {|i| ('A'..'Z').to_a[i.to_i(26)]}.join end 

根据sawa的回答,我想要一种独立工作的方法,尽管是递归的,以达到预期的结果:

 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