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

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

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

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

Ответы [ 28 ]

1 голос
/ 11 августа 2011

Еще один Delphi один:

function ExcelColumnNumberToLetter(col: Integer): string;
begin
  if (col <= 26) then begin
    Result := Chr(col + 64);
  end
  else begin
    col := col-1;
    Result := ExcelColumnNumberToLetter(col div 26) + ExcelColumnNumberToLetter((col mod 26) + 1);
  end;
end;
1 голос
/ 07 января 2010

Получить номер столбца из его названия

Java:

public int getColNum (String colName) {

    //remove any whitespace
    colName = colName.trim();

    StringBuffer buff = new StringBuffer(colName);

    //string to lower case, reverse then place in char array
    char chars[] = buff.reverse().toString().toLowerCase().toCharArray();

    int retVal=0, multiplier=0;

    for(int i = 0; i < chars.length;i++){
        //retrieve ascii value of character, subtract 96 so number corresponds to place in alphabet. ascii 'a' = 97 
        multiplier = (int)chars[i]-96;
        //mult the number by 26^(position in array)
        retVal += multiplier * Math.pow(26, i);
    }
    return retVal;
}
1 голос
/ 26 февраля 2010

Получить имя столбца из int в Java ( подробнее здесь ):

public String getColName (int colNum) {

   String res = "";

   int quot = colNum;
   int rem;        
    /*1. Subtract one from number.
    *2. Save the mod 26 value.
   *3. Divide the number by 26, save result.
   *4. Convert the remainder to a letter.
   *5. Repeat until the number is zero.
   *6. Return that bitch...
   */
    while(quot > 0)
    {
        quot = quot - 1;
        rem = quot % 26;
        quot = quot / 26;

        //cast to a char and add to the beginning of the string
        //add 97 to convert to the correct ascii number
        res = (char)(rem+97) + res;            
    }   
    return res;
}
0 голосов
/ 18 апреля 2009

Вот CFML:

<cffunction name="ColToNum" returntype="Numeric">
    <cfargument name="Input" type="String" />
    <cfset var Total = 0 />
    <cfset var Pos = 0 />

    <cfloop index="Pos" from="1" to="#Len(Arguments.Input)#">
        <cfset Total += 26^(Pos-1) * ( Asc( UCase( Mid(Arguments.Input,Pos,1) ) ) - 64 ) />
    </cfloop>

    <cfreturn Total />
</cffunction>

<cfoutput>
    #ColToNum('AABCCE')#
</cfoutput>


И поскольку я в странном настроении, вот версия CFScript:

function ColToNum ( Input )
{
    var Total = 0;

    for ( var Pos = 1 ; Pos <= Len(Arguments.Input) ; Pos++ )
    {
        Total += 26^(Pos-1) * ( Asc( UCase( Mid(Arguments.Input,Pos,1) ) ) - 64 );
    }

    return Total;
}

WriteOutput( ColToNum('AABCCE') );
0 голосов
/ 23 января 2013

В Википедии есть хорошие объяснения и алгоритмы

http://en.wikipedia.org/wiki/Hexavigesimal

public static String toBase26(int value){
    // Note: This is a slightly modified version of the Alphabet-only conversion algorithm

    value = Math.abs(value);
    String converted = "";

    boolean iteration = false;

    // Repeatedly divide the number by 26 and convert the
    // remainder into the appropriate letter.
    do {
        int remainder = value % 26;

        // Compensate for the last letter of the series being corrected on 2 or more iterations.
        if (iteration && value < 25) {
            remainder--;
        }

        converted = (char)(remainder + 'A') + converted;
        value = (value - remainder) / 26;

        iteration = true;
    } while (value > 0);

    return converted;    
}
0 голосов
/ 18 июня 2011

Используя потрясающий код Mathematica, созданный мистером Wizard'ом, но избавляясь от загадочно чистой функции!

columnNumber[name_String] := FromDigits[ToCharacterCode[name] - 64, 26]
0 голосов
/ 19 апреля 2009

другой [более загадочный] пример эрланга:

col2int(String) -> col2int(0,String).
col2int(X,[A|L]) when A >= 65, A =< 90 ->
col2int(26 * X + A - 65 + 1, L);
col2int(X,[]) -> X.

и обратная функция:

int2col(Y) when Y > 0 -> int2col(Y,[]).
int2col(0,L) -> L;
int2col(Y,L) when Y rem 26 == 0 -> 
   int2col(Y div 26 - 1,[(26+65-1)|L]);
int2col(Y,L) ->
   P = Y rem 26,
   int2col((Y - P) div 26,[P + 65-1|L]).
0 голосов
/ 17 октября 2015

Вот еще одна версия этого кода на Python:

keycode=1
for i in range (1,len(word)):
    numtest[i]=word[i-1]
    keycode = keycode*26*int(wordtest[numtest[i]])
last=word[-1:]
keycode=keycode+int(wordtest[last])
print(keycode)
print(bin(keycode))
#Numtest and wordtest are dictionaries.
0 голосов
/ 18 апреля 2009

Common Lisp:

(defun excel->number (string)
  "Converts an Excel column name to a column number."
  (reduce (lambda (a b) (+ (* a 26) b))
          string
          :key (lambda (x) (- (char-int x) 64))))

редактировать: обратная операция:

(defun number->excel (number &optional acc)
  "Converts a column number to Excel column name."
  (if (zerop number)
      (concatenate 'string acc)
      (multiple-value-bind (rest current) (floor number 26)
        (if (zerop current)
            (number->excel (- rest 1) (cons #\Z acc))
            (number->excel rest (cons (code-char (+ current 64)) acc))))))
0 голосов
/ 18 апреля 2009

Это в основном число в базе 26, с той разницей, что число использует не 0-9, а затем буквы, а только буквы.

...