Programming Riddle: How might you translate an Excel column name to a number?

前端 未结 28 1116
[愿得一人]
[愿得一人] 2020-11-29 22:26

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 actu

相关标签:
28条回答
  • 2020-11-29 22:38

    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;    
    }
    
    0 讨论(0)
  • 2020-11-29 22:39

    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
    
    0 讨论(0)
  • 2020-11-29 22:39

    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;
    }
    
    0 讨论(0)
  • 2020-11-29 22:40

    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;
    }
    
    0 讨论(0)
  • 2020-11-29 22:41

    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;
    }
    
    0 讨论(0)
  • 2020-11-29 22:41

    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?

    0 讨论(0)
提交回复
热议问题