编程谜语:如何将 Excel 列名称转换为数字?

发布于 2024-07-17 12:09:08 字数 201 浏览 6 评论 0原文

最近,我在一次工作面试中被要求解决一个编程难题,我认为分享这个难题会很有趣。 这是关于将 Excel 列字母转换为实际数字,如果您还记得的话,Excel 用从 A 到 Z 的字母命名其列,然后顺序为 AA、AB、AC...AZ、BA、BB 等。

您必须编写接受字符串作为参数(如“AABCCE”)并返回实际列号的函数。

该解决方案可以采用任何语言。

I was recently asked in a job interview to resolve a programming puzzle that I thought it would be interesting to share. It's about translating Excel column letters to actual numbers, if you recall, Excel names its columns with letters from A to Z, and then the sequence goes AA, AB, AC... AZ, BA, BB, etc.

You have to write a function that accepts a string as a parameter (like "AABCCE") and returns the actual column number.

The solution can be in any language.

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

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

发布评论

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

评论(28

纵山崖 2024-07-24 12:09:09

对我来说听起来像是一个标准的简化:

Python:

def excel2num(x): 
    return reduce(lambda s,a:s*26+ord(a)-ord('A')+1, x, 0)

C#:

int ExcelToNumber(string x) {
    return x.Aggregate(0, (s, c) => s * 26 + c - 'A' + 1 );
}

Sounds like a standard reduce to me:

Python:

def excel2num(x): 
    return reduce(lambda s,a:s*26+ord(a)-ord('A')+1, x, 0)

C#:

int ExcelToNumber(string x) {
    return x.Aggregate(0, (s, c) => s * 26 + c - 'A' + 1 );
}
萝莉病 2024-07-24 12:09:09

我很久以前为一些 Python 脚本写过这个:

def index_to_int(index):
    s = 0
    pow = 1
    for letter in index[::-1]:
        d = int(letter,36) - 9
        s += pow * d
        pow *= 26
    # excel starts column numeration from 1
    return s

I wrote this ages ago for some Python script:

def index_to_int(index):
    s = 0
    pow = 1
    for letter in index[::-1]:
        d = int(letter,36) - 9
        s += pow * d
        pow *= 26
    # excel starts column numeration from 1
    return s
七颜 2024-07-24 12:09:09

从 STDIN 读取列名并打印出其相应的编号:

perl -le '$x = $x * 26 - 64 + ord for <> =~ /./g; print $x'

注意事项:采用 ASCII。

编辑:" 替换为 ',这样您的 shell 就不会在字符串中插入 $x

Read a column name from STDIN and print out its corresponding number:

perl -le '$x = $x * 26 - 64 + ord for <> =~ /./g; print $x'

Caveats: Assumes ASCII.

EDIT: Replaced " with ' so that your shell won't interpolate $x in the string.

暗喜 2024-07-24 12:09:09

巧合的是我用javascript解决了同样的问题

$(function() { //shorthand document.ready function
    var getNumber = function(x) {
        var result = 0;
        var multiplier = 1;
        for ( var i = x.length-1; i >= 0; i--)
        { 
            var value = ((x[i].charCodeAt(0) - "A".charCodeAt(0)) + 1);
            result = result + value * multiplier;
            multiplier = multiplier * 26;
        }
        return result;
    };
    
    $('#form').on('submit', function(e) { //use on if jQuery 1.7+
        e.preventDefault();  //prevent form from submitting
        var data = $("#number").val();
        $('#answer').text(getNumber(data));
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="form">
<input type="text" id="number"></input>
    <button>submit</button>
</form>
<p id="answer"></p>

    var getNumber = function(x) {
        var result = 0;
        var multiplier = 1;
        for ( var i = x.length-1; i >= 0; i--)
        { 
            var value = ((x[i].charCodeAt(0) - "A".charCodeAt(0)) + 1);
            result = result + value * multiplier;
            multiplier = multiplier * 26;
        }
        return result;
    };

http://jsfiddle.net/M7Xty/1/

Coincidentally I've solved the same problem using javascript

$(function() { //shorthand document.ready function
    var getNumber = function(x) {
        var result = 0;
        var multiplier = 1;
        for ( var i = x.length-1; i >= 0; i--)
        { 
            var value = ((x[i].charCodeAt(0) - "A".charCodeAt(0)) + 1);
            result = result + value * multiplier;
            multiplier = multiplier * 26;
        }
        return result;
    };
    
    $('#form').on('submit', function(e) { //use on if jQuery 1.7+
        e.preventDefault();  //prevent form from submitting
        var data = $("#number").val();
        $('#answer').text(getNumber(data));
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="form">
<input type="text" id="number"></input>
    <button>submit</button>
</form>
<p id="answer"></p>

    var getNumber = function(x) {
        var result = 0;
        var multiplier = 1;
        for ( var i = x.length-1; i >= 0; i--)
        { 
            var value = ((x[i].charCodeAt(0) - "A".charCodeAt(0)) + 1);
            result = result + value * multiplier;
            multiplier = multiplier * 26;
        }
        return result;
    };

http://jsfiddle.net/M7Xty/1/

若水微香 2024-07-24 12:09:09

哈 - 已经在我们的代码库中写入了它 - 大约 3 次不同的时间:(

%% @doc Convert an string to a decimal integer
%% @spec b26_to_i(string()) -> integer()

b26_to_i(List) when is_list(List) ->
    b26_to_i(string:to_lower(lists:reverse(List)),0,0).

%% private functions
b26_to_i([], _Power, Value) -> 
    Value;

b26_to_i([H|T],Power,Value)->
    NewValue = case (H > 96) andalso (H < 123) of
                   true ->
                       round((H - 96) * math:pow(26, Power));
                   _    ->
                       exit([H | T] ++ " is not a valid base 26 number")
               end,
    b26_to_i(T, Power + 1, NewValue + Value).

谜语是它实际上不是数字的 Base26 表示(我们在这里的函数名称中欺骗了自己),因为其中没有 0 :

顺序是
A、B、C ... Z、AA、AB、AC

而非:
A、B、C ...Z、BA、BB、BC

(语言是 Erlang,mais oui)。

Hah - written it already in our code base - about 3 different times :(

%% @doc Convert an string to a decimal integer
%% @spec b26_to_i(string()) -> integer()

b26_to_i(List) when is_list(List) ->
    b26_to_i(string:to_lower(lists:reverse(List)),0,0).

%% private functions
b26_to_i([], _Power, Value) -> 
    Value;

b26_to_i([H|T],Power,Value)->
    NewValue = case (H > 96) andalso (H < 123) of
                   true ->
                       round((H - 96) * math:pow(26, Power));
                   _    ->
                       exit([H | T] ++ " is not a valid base 26 number")
               end,
    b26_to_i(T, Power + 1, NewValue + Value).

The riddle is that it isn't actually a Base26 representation of a number (we are lying to ourselves in our function name here) because there is no 0 in it.

The sequence is:
A, B, C ... Z, AA, AB, AC

and not:
A, B, C ...Z, BA, BB, BC

(the language is Erlang, mais oui).

甜妞爱困 2024-07-24 12:09:09

您可以在 C 中执行此操作,如下所示:

unsigned int coltonum(char * string)
{
   unsigned result = 0;
   char ch;

   while(ch = *string++)
      result = result * 26 + ch - 'A' + 1;

  return result;
}

无错误检查,仅适用于大写字符串,字符串必须以 null 结尾。

You can do this in C like this:

unsigned int coltonum(char * string)
{
   unsigned result = 0;
   char ch;

   while(ch = *string++)
      result = result * 26 + ch - 'A' + 1;

  return result;
}

No error checking, only works for upper case strings, string must be null terminated.

摘星┃星的人 2024-07-24 12:09:09

从 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;
}

Get the column number from its name

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;
}
Saygoodbye 2024-07-24 12:09:09

假设 A 列 = 1

int GetColumnNumber(string columnName)
{
  int sum = 0;
  int exponent = 0;
  for(int i = columnName.Length - 1; i>=0; i--)
  {
    sum += (columnName[i] - 'A' + 1) *  (GetPower(26, exponent));
    exponent++;
  }
  return sum;
}

int GetPower(int number, int exponent)
{
  int power = 1;
  for(int i=0; i<exponent; i++)
    power *= number;
  return power;
}

Assuming column A = 1

int GetColumnNumber(string columnName)
{
  int sum = 0;
  int exponent = 0;
  for(int i = columnName.Length - 1; i>=0; i--)
  {
    sum += (columnName[i] - 'A' + 1) *  (GetPower(26, exponent));
    exponent++;
  }
  return sum;
}

int GetPower(int number, int exponent)
{
  int power = 1;
  for(int i=0; i<exponent; i++)
    power *= number;
  return power;
}
醉城メ夜风 2024-07-24 12:09:09

从 Java 中的 int 获取列名(在此处阅读更多信息):

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;
}

Get a column name from an int in Java(read more here):

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;
}
蘸点软妹酱 2024-07-24 12:09:09

警告:这两个版本都仅假定大写字母 A 到 Z。任何其他情况都会导致计算错误。 添加一些错误检查和/或大写来改进它们并不难。

斯卡拉·

def excel2Number(excel : String) : Int = 
  (0 /: excel) ((accum, ch) => accum * 26 + ch - 'A' + 1)

哈斯克尔

excel2Number :: String -> Int
excel2Number = flip foldl 0 $ \accum ch -> accum * 26 + fromEnum ch - fromEnum 'A' + 1

Caveat: both of these versions assume only uppercase letters A to Z. Anything else causes a miscalculation. It wouldn't be hard to add a bit of error checking and/or uppercasing to improve them.

Scala

def excel2Number(excel : String) : Int = 
  (0 /: excel) ((accum, ch) => accum * 26 + ch - 'A' + 1)

Haskell

excel2Number :: String -> Int
excel2Number = flip foldl 0 $ \accum ch -> accum * 26 + fromEnum ch - fromEnum 'A' + 1
旧竹 2024-07-24 12:09:09

另一个德尔福的:

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;

Another Delphi one:

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;
沉鱼一梦 2024-07-24 12:09:09

另一个Java:

public static int convertNameToIndex(String columnName) {
    int index = 0;
    char[] name = columnName.toUpperCase().toCharArray();

    for(int i = 0; i < name.length; i++) {
        index *= 26;
        index += name[i] - 'A' + 1;
    }

    return index;
}

Another Java:

public static int convertNameToIndex(String columnName) {
    int index = 0;
    char[] name = columnName.toUpperCase().toCharArray();

    for(int i = 0; i < name.length; i++) {
        index *= 26;
        index += name[i] - 'A' + 1;
    }

    return index;
}
魂归处 2024-07-24 12:09:09

简单的Java解决方案-->

public class ColumnName {

public static int colIndex(String col)
{   int index=0;
    int mul=0;
    for(int i=col.length()-1;i>=0;i--)
    {   
        index  += (col.charAt(i)-64) * Math.pow(26, mul);
        mul++;
    }
    return index;
}

public static void main(String[] args) {

    System.out.println(colIndex("AAA"));

}

Easy Java solution -->

public class ColumnName {

public static int colIndex(String col)
{   int index=0;
    int mul=0;
    for(int i=col.length()-1;i>=0;i--)
    {   
        index  += (col.charAt(i)-64) * Math.pow(26, mul);
        mul++;
    }
    return index;
}

public static void main(String[] args) {

    System.out.println(colIndex("AAA"));

}
烟花易冷人易散 2024-07-24 12:09:09

将字符串视为以 26 为基数、用 A、B、... Z 表示的数字的列号的反转是否有帮助?

Does it help to think of the string as the reverse of the column number in base 26 with digits represented by A, B, ... Z?

夏了南城 2024-07-24 12:09:09

这基本上是一个以 26 为基数的数字,不同之处在于该数字不使用 0-9 和字母,而是字母。

This is basically a number in base 26, with the difference that the number doesn't use 0-9 and then letters but only letters.

琉璃梦幻 2024-07-24 12:09:09

这是一个 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') );

Here's a CFML one:

<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>

And because I'm in an odd mood, here's a CFScript version:

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') );
优雅的叶子 2024-07-24 12:09:09

另一个[更神秘的] erlang 示例:

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]).

another [more cryptic] erlang example:

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

and inverse function:

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]).
对你的占有欲 2024-07-24 12:09:09

德尔福:

// 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;

-阿尔。

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;

-Al.

掐死时间 2024-07-24 12:09:09

稍微相关的是,更好的挑战是相反的:给定列号,找到字符串形式的列标签。

我为 KOffice 实现的 Qt 版本:

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;
}

Slightly related, the better challenge is the other way around: given the column number, find the column label as string.

Qt version as what I implemented for 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;
}
困倦 2024-07-24 12:09:09

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))))))

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))))

edit: the inverse operation:

(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))))))
谈情不如逗狗 2024-07-24 12:09:09

该版本纯粹是功能性的,并且允许替代的“代码”序列,例如,如果您只想使用字母“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)
    }
}

This version is purely functional and permits alternative 'code' sequences, for example if you wanted to only uses the letters 'A' to 'C'. In Scala, with a suggestion from dcsobral.

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

    name.foldLeft(0) { (sum, letter) =>
        (sum * code.length) + (code.indexOf(letter) + 1)
    }
}
仙女 2024-07-24 12:09:09
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

ps 我的第一个 Python 脚本!

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. My first Python script!

你的呼吸 2024-07-24 12:09:09

在数学中:

FromDigits[ToCharacterCode@# - 64, 26] &

In Mathematica:

FromDigits[ToCharacterCode@# - 64, 26] &
云之铃。 2024-07-24 12:09:09

使用Mr. Wizard 令人敬畏的Mathematica 代码,但摆脱了神秘的纯函数!

columnNumber[name_String] := FromDigits[ToCharacterCode[name] - 64, 26]

Using Mr. Wizard's awesome Mathematica code, but getting rid of the cryptic pure function!

columnNumber[name_String] := FromDigits[ToCharacterCode[name] - 64, 26]
吲‖鸣 2024-07-24 12:09:09

维基百科有很好的解释和算法

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;    
}

Wikipedia has good explanations and algos

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;    
}
赏烟花じ飞满天 2024-07-24 12:09:09

...只需要一个 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;
//  …

…just needed a solution for PHP. This is what I came up with:

/**
 * 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;
}

Of course the script can be shortened a little by just combining some stuff into one line of code within the foreach loop:

//  …
$columnNumber = $columnNumber * 26 + ord($character) - ord('a') + 1;
//  …
探春 2024-07-24 12:09:09

在Python中,不使用reduce:

def transform(column_string):
    return sum((ascii_uppercase.index(letter)+1) * 26**position for position, letter in enumerate(column_string[::-1]))

In Python, without reduce:

def transform(column_string):
    return sum((ascii_uppercase.index(letter)+1) * 26**position for position, letter in enumerate(column_string[::-1]))
白昼 2024-07-24 12:09:09

下面是此代码的 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.

Here is another version of this code in 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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文