我想生成对应于数字的字母序列,即“A”,“DE”“GJE”等。前26个很容易,因此3返回“C”,26返回“Z”,27返回“AA”,28“AB”,依此类推。
我无法弄清楚的是如何做到这一点所以它将处理传入的任何数字。所以如果我传入4123我应该回到3个字母的组合,因为(26 * 26 * 26)允许最多+17,000种组合。
有什么建议吗?
答案 0 :(得分:11)
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"
答案 1 :(得分:10)
对@sawa原创的Ruby 2.0答案进行了调整,因为我无法按原样运行:
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
# => ""
答案 2 :(得分:5)
字符串确实有succ
方法,因此它们可用于范围。 “Z”的后继者恰好是“AA”,所以这有效:
h = {}
('A'..'ZZZ').each_with_index{|w, i| h[i+1] = w }
p h[27] #=> "AA"
答案 3 :(得分:3)
我喜欢这个答案:https://stackoverflow.com/a/17785576/514483
number.to_s(26).tr("0123456789abcdefghijklmnopq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
答案 4 :(得分:2)
使用找到here的基本转换方法。我也改变了它,因为我们在这个编号系统中缺少“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"
答案 5 :(得分:2)
def letter_sequence(n)
n.to_s(26).each_char.map {|i| ('A'..'Z').to_a[i.to_i(26)]}.join
end
答案 6 :(得分:0)
根据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
答案 7 :(得分:0)
class Numeric
# 'z' is placed in the begining of the array because 26 % 26 is 0 not 26
Alph = ['z'] + ("a".."y").to_a
def to_alph
# if self is 0 or negative return a blank string.
# this is also used to end the recursive chain of to_alph calls
# so don't replace this with raising an error or returning anything else
return '' if self < 1
# (otherwise) return two concatenated strings:
# the right side is the letter for self modules 26
# the left side is comprised of:
# 1. minus one, because this is not a zero-based numbering system.
# therefore, round numbers (26, 52...) should return one digit 'z'
# instead of two digits 'aa' or 'ba'.
# 2. divide by 26 and call to_alph on that.
# this repeats recursively for every digit of the final string,
# plus once more that will return '' to end the recursion chain.
return ((self - 1) / 26).to_alph + Alph[self % 26]
end
end
答案 8 :(得分:0)
您可以通过从序数中减去 96 来获得字符在字母表中的数字位置,如下所示:
"a".ord - 96
=> 1
"z".ord - 96
=> 26
您还可以通过添加 96 来按字母数字位置获取字母字符,如下所示:
(1 + 96).chr
=> "a"
(26 + 96).chr
=> "z"