Преобразование чисел в заголовки столбцов Excel

Это проблема на 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)
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
0
0
34
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы проверили этот ответ? Это похоже на то, о чем вы просите. Я также делюсь кодом следующим образом.

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))
Ответ принят как подходящий

Смог найти неисправность, но не нашел элегантного способа решения проблемы. Как вы могли заметить, код всегда дает сбой всякий раз, когда вы добираетесь до Z и в нем больше одной буквы. Все потому, что множители, которые должны быть, например, 2 и 26, то есть БЗ, становятся 3 и 0. И этот ноль приводит к проблеме. Вот хак, который заставляет код работать. Все то же самое, кроме оператора if (и num = num - (factor*(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]

Эти операторы if просто фиксируют эти случаи «Z», которые происходят всякий раз, когда в результате есть более одной буквы.

Огромная работа, Джанзаиб! Огромное спасибо!

NaiveBae 24.04.2022 20:28

Другие вопросы по теме