Загадка программирования: Как вы можете перевести имя столбца Excel в число? - PullRequest
46 голосов
/ 18 апреля 2009

Меня недавно попросили на собеседовании, чтобы решить загадку программирования, которой, я думаю, было бы интересно поделиться. Речь идет о переводе букв столбцов Excel в фактические числа, если вы помните, Excel называет свои столбцы буквами от A до Z, а затем последовательность идет AA, AB, AC ... AZ, BA, BB и т. Д.

Вы должны написать функцию, которая принимает строку в качестве параметра (например, «AABCCE») и возвращает фактический номер столбца.

Решение может быть на любом языке.

Ответы [ 28 ]

0 голосов
/ 17 июня 2009

Эта версия является чисто функциональной и допускает альтернативные «кодовые» последовательности, например, если вы хотите использовать только буквы «A» - «C». В Scala, с предложением от dcsobral.

def columnNumber(name: String) = {
    val code = 'A' to 'Z'

    name.foldLeft(0) { (sum, letter) =>
        (sum * code.length) + (code.indexOf(letter) + 1)
    }
}
0 голосов
/ 21 апреля 2009
def ExcelColumnToNumber(ColumnName):
    ColNum = 0
    for i in range(0, len(ColumnName)):
        # Easier once formula determined: 'PositionValue * Base^Position'
        # i.e. AA=(1*26^1)+(1*26^0)   or  792=(7*10^2)+(9*10^1)+(2*10^0)
        ColNum += (int(ColumnName[i],36) -9) * (pow(26, len(ColumnName)-i-1))
    return ColNum

p.s. Мой первый скрипт на Python!

0 голосов
/ 20 апреля 2009

Delphi:

// convert EXcel column name to column number 1..256
// case-sensitive; returns 0 for illegal column name
function cmColmAlfaToNumb( const qSRC : string ) : integer;
var II : integer;
begin
   result := 0;
   for II := 1 to length(qSRC) do begin
      if (qSRC[II]<'A')or(qSRC[II]>'Z') then begin
         result := 0;
         exit;
      end;
      result := result*26+ord(qSRC[II])-ord('A')+1;
   end;
   if result>256 then result := 0;
end;

-Аль.

0 голосов
/ 07 ноября 2014

… просто нужно решение для PHP . Вот что я придумал:

/**
 * Calculates the column number for a given column name.
 *
 * @param string $columnName the column name: "A", "B", …, "Y", "Z", "AA", "AB" … "AZ", "BA", … "ZZ", "AAA", …
 *
 * @return int the column number for the given column name: 1 for "A", 2 for "B", …, 25 for "Y", 26 for "Z", 27 for "AA", … 52 for "AZ", 53 for "BA", … 703 for "AAA", …
 */
function getColumnNumber($columnName){
    //  the function's result
    $columnNumber = 0;

    //  at first we need to lower-case the string because we calculate with the ASCII value of (lower-case) "a"
    $columnName = strtolower($columnName);
    //  ASCII value of letter "a"
    $aAsciiValue = ord('a') - 1;

    //  iterate all characters by splitting the column name
    foreach (str_split($columnName) as $character) {
        //  determine ASCII value of current character and substract with that one from letter "a"
        $characterNumberValue = ord($character) - $aAsciiValue;

        //  through iteration and multiplying we finally get the previous letters' values on base 26
        //  then we just add the current character's number value
        $columnNumber = $columnNumber * 26 + $characterNumberValue;
    }

    //  return the result
    return $columnNumber;
}

Конечно, скрипт можно немного сократить, просто объединив некоторые вещи в одну строку кода в цикле foreach:

//  …
$columnNumber = $columnNumber * 26 + ord($character) - ord('a') + 1;
//  …
0 голосов
/ 14 июля 2015

В Python, без уменьшения:

def transform(column_string):
    return sum((ascii_uppercase.index(letter)+1) * 26**position for position, letter in enumerate(column_string[::-1]))
0 голосов
/ 17 мая 2011

В Mathematica:

FromDigits[ToCharacterCode@# - 64, 26] &
0 голосов
/ 18 апреля 2009

Помогает ли это думать о строке как об обратном номеру столбца в базе 26 с цифрами, представленными A, B, ... Z?

0 голосов
/ 19 апреля 2009

Немного связано, тем сложнее будет наоборот: по номеру столбца найти метку столбца как строку.

Версия Qt как то, что я реализовал для KOffice:

QString columnLabel( unsigned column )
{
  QString str;
  unsigned digits = 1;
  unsigned offset = 0;

  column--;
  for( unsigned limit = 26; column >= limit+offset; limit *= 26, digits++ )
    offset += limit;

  for( unsigned c = column - offset; digits; --digits, c/=26 )
    str.prepend( QChar( 'A' + (c%26) ) );

  return str;
}
...