将数字转换为Excel列标题

发布于 2025-01-23 12:49:25 字数 1653 浏览 3 评论 0原文

这是Leetcode上的问题,被归类为“简单”。我已经去了几个小时,甚至打电话给同事。我无法弄清楚逻辑中的错。我不是在寻找解决问题的完全不同的解决方案。如果有人可以指出我的方法出了什么问题,我会很感激。

这个想法是将int转换为表示为Excel列标题的字符串(1 ='a',2 ='b'... 27 ='aa'等)。这是我的代码,带有评论。该代码适用于许多输入(例如735 - >'abg'),但对其他输入失败(例如,702 - >'zz')。

def numToCol(n):

  # Generate a key such that {1:'A', 2:'B', 3:'C'... 26:'Z'} (this works fine)
  key = {}
  for i in range(65, 91):
    key[i-64] = chr(i)

  # According to Wikipedia, the number of digits in the bijective base-k 
  # numeral representing a nonnegative integer n is floor(logk((n+1)*(k-1)))

  # exp = num of letters in final string
  exp = int(math.log((n+1)*25, 26)) # int() rounds it down
  col_name = ''
  num = n

  # The final number is represented by a(26**0) + b(26**1) + c(26**2) + ...
  # If exp = 3, then there are 3 letters in the final string, so we need to find
  # a(26**2) + b(26**1) + c(26**0).

  # If exp = 3, i iterates over 2, 1, 0.
  for i in range(exp-1, -1, -1):
    # factor = how many 26**i's there are in num, rounded down
    factor = int(num/(26**i))
    # add to the string the letter associated with that factor
    col_name = col_name + key[factor]
    # update the number for next iteration
    num = num - (factor*(26**i))

  return col_name

这是我写的一个函数,以转向反向方向(将字符串转换为int)。这有助于查看预期的结果应该是什么。它已确认工作。

def colToNum(string):
  '''
  Converts an upper-case string (e.g., 'ABC') to numbers as if they were
  column headers in Excel.
  '''
  key = {}
  for i in range(65, 91):
    key[chr(i)] = i-64

  new = []
  for idx, val in enumerate(string[::-1]):
    new.append(key[val] * 26**idx)

  return sum(new)

This is a problem on LeetCode and it's classified as "easy." I've been at this for hours, even called in a colleague. I can't figure out the fault in my logic. I'm not looking for a completely different solution to the problem. I'd just be grateful if someone could point out what's wrong with my approach.

The idea is to convert an int to a string that is represented as an Excel column header (1='A', 2='B' ... 27='AA', etc.). Here is my code, with comments. The code works for many inputs (e.g., 735 -> 'ABG'), but fails on others (e.g., 702 -> 'ZZ').

def numToCol(n):

  # Generate a key such that {1:'A', 2:'B', 3:'C'... 26:'Z'} (this works fine)
  key = {}
  for i in range(65, 91):
    key[i-64] = chr(i)

  # According to Wikipedia, the number of digits in the bijective base-k 
  # numeral representing a nonnegative integer n is floor(logk((n+1)*(k-1)))

  # exp = num of letters in final string
  exp = int(math.log((n+1)*25, 26)) # int() rounds it down
  col_name = ''
  num = n

  # The final number is represented by a(26**0) + b(26**1) + c(26**2) + ...
  # If exp = 3, then there are 3 letters in the final string, so we need to find
  # a(26**2) + b(26**1) + c(26**0).

  # If exp = 3, i iterates over 2, 1, 0.
  for i in range(exp-1, -1, -1):
    # factor = how many 26**i's there are in num, rounded down
    factor = int(num/(26**i))
    # add to the string the letter associated with that factor
    col_name = col_name + key[factor]
    # update the number for next iteration
    num = num - (factor*(26**i))

  return col_name

Here is a function I wrote to go the reverse direction (convert string to int). This helps to see what the expected result should be. It's confirmed to work.

def colToNum(string):
  '''
  Converts an upper-case string (e.g., 'ABC') to numbers as if they were
  column headers in Excel.
  '''
  key = {}
  for i in range(65, 91):
    key[chr(i)] = i-64

  new = []
  for idx, val in enumerate(string[::-1]):
    new.append(key[val] * 26**idx)

  return sum(new)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请爱~陌生人 2025-01-30 12:49:25

能够找到故障,但找不到解决问题的优雅方法。您可能已经注意到,每当您到达Z时,代码总是会失败,并且有多个字母。那是因为应有的因素,例如2和26,含义为Bz,变为3和0。这零导致了问题。这是设法使代码工作的黑客。除了if-statement(和num = num-(因子*(26 ** i))是否已移动),

for i in range(exp-1, -1, -1):
    # factor = how many 26**i's there are in num, rounded down
    
    factor = int(num/(26**i))
    num = num - (factor*(26**i))
    
    if num == 0 and i!=0:
        factor -=1
        num = 26

    # add to the string the letter associated with that factor
    col_name = col_name + key[factor]

这 一切都是相同的每当结果中有多个字母时,就会发生。

Was able to find the fault, but didn't find an elegant way of solving the problem. As you might have noticed, the code always fails whenever you get to Z and there is more than one letter. That's because the factors that should be, for example, 2 and 26, meaning BZ, become 3 and 0. And this zero leads to the problem. Here is the hack that manages to make the code work. Everything is the same except for the if-statement (and num = num - (factor*(26**i)) has been moved up)

for i in range(exp-1, -1, -1):
    # factor = how many 26**i's there are in num, rounded down
    
    factor = int(num/(26**i))
    num = num - (factor*(26**i))
    
    if num == 0 and i!=0:
        factor -=1
        num = 26

    # add to the string the letter associated with that factor
    col_name = col_name + key[factor]

This if-statements just fixes these "Z" cases that happen whenever there is more than one letter in the result.

来日方长 2025-01-30 12:49:25

您是否检查这个答案?看起来像您要的地区。我也正在分享以下代码。

def excel_column_number_to_name(column_number):
    output = ""
    index = column_number - 1
    while index >= 0:
        character = chr((index % 26) + ord('A'))
        output = output + character
        index = index // 26 - 1

    return output[::-1]


for i in xrange(1, 1024):
    print "%4d : %s" % (i, excel_column_number_to_name(i))

Did you check this answer? That one looks like what you area asking for. I am sharing the code as following as well.

def excel_column_number_to_name(column_number):
    output = ""
    index = column_number - 1
    while index >= 0:
        character = chr((index % 26) + ord('A'))
        output = output + character
        index = index // 26 - 1

    return output[::-1]


for i in xrange(1, 1024):
    print "%4d : %s" % (i, excel_column_number_to_name(i))
梦境 2025-01-30 12:49:25

减去1并生成剩余的模量26。0-25代表AZ。重复:

def num_to_col(num):
    if num < 1:
        raise ValueError('num must be >= 1')
    result = ''
    while num:
        num, rem = divmod(num - 1, 26)
        result = chr(ord('A') + rem) + result
    return result

# tests
for num in (1, 26, 26+1, 26*2, 26*2+1, 26*26+25,
            26*26+26, 26*26+26+1, 735,
            26*26*26+26*26+26, 26*26*26+26*26+26+1):
    print(f'{num:5} {num_to_col(num)}')

输出:

    1 A
   26 Z
   27 AA
   52 AZ
   53 BA
  701 ZY
  702 ZZ
  703 AAA
  735 ABG
18278 ZZZ
18279 AAAA

Subtract 1 and generate a remainder modulo 26. 0-25 represents A-Z. Repeat:

def num_to_col(num):
    if num < 1:
        raise ValueError('num must be >= 1')
    result = ''
    while num:
        num, rem = divmod(num - 1, 26)
        result = chr(ord('A') + rem) + result
    return result

# tests
for num in (1, 26, 26+1, 26*2, 26*2+1, 26*26+25,
            26*26+26, 26*26+26+1, 735,
            26*26*26+26*26+26, 26*26*26+26*26+26+1):
    print(f'{num:5} {num_to_col(num)}')

Output:

    1 A
   26 Z
   27 AA
   52 AZ
   53 BA
  701 ZY
  702 ZZ
  703 AAA
  735 ABG
18278 ZZZ
18279 AAAA
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文