算法:根據excel列數計算列號

在微軟的5面的時候遇到了一個算法題,根據excel列號計算列數以及根據列號計算列數,因爲面試時候答得很差,所以這裏記錄一下實現思路。java


首先講下題目:根據excel列號計算列數以及根據列號計算列數,excel中的列數是使用字母表示的,即A,B,C...Z,AA...,ZZ....這種狀況,假設咱們輸入1,那麼輸出結果爲1,輸入27,輸出結果爲AA,一次類推。面試

思路:算法

這個題目本質上能夠簡化爲一個26進制轉10進制的題目,那麼思路就很容易了:excel

/**
     * 本質上是一個26進制轉10進制的算法,因此直接從個位數一次往最高位數進行取值的操做,而後轉換成對應字母便可
     * 注:取餘後0表明恰好知足26,其餘的正常。
     * 算法思路:進行循環的操做過程
     * Step1.[取餘] 用指定天然數n取餘26,獲得一個餘數m。若是m = 0,置m←26。
     * Step2.[轉換爲字符] 將m映射爲字符c,映射規則是{1-26}->{A-Z}。而後將c拼接到26進制值s的左邊,也就是置s←c + s。
     * Step3.[去餘降冪] 置n←(n–m)/26。若是n > 0,則回到Step1繼續執行,不然進入Step4。
     * Step4.[結束] 返回s。
     * @param num
     * @return
     */
    public static String numCovertLetter(int num) {
        if (num <= 0) {
            throw new RuntimeException("參數必須大於0");
        }
        String str = "";
        while (num > 0) {
            int res = num % 26;
            if (res == 0) {
                res = 26;
            }
            str = (char) (res + 64)+ str;
            num = (num - res) / 26;
        }
        return str;
    }

那麼換位思考一下,若是須要求出其餘進制轉10進制的算法,咱們抽出26,改爲傳遞的方式便可:code

/**
     * 衍生出其餘進制轉換爲10進制的方式
     * @param num
     * @param pos
     * @return
     */
    public static String numCovertLetter(int num,int pos) {
        if (num <= 0) {
            throw new RuntimeException("參數必須大於0");
        }
        String str = "";
        while (num > 0) {
            int residue = num % pos;
            if (residue == 0) {
                residue = pos;
            }
            str = residue+ str;
            num = (num - residue) / pos;
        }
        return str;
    }

Ok,咱們在進行一個根據列號求列數的方式:string

/**
     *
     * @param string
     * @return
     */
    public static int covertLetterToNum(String string) {
        char[] chars=string.toCharArray();
        int value=0;
        int pos=1;
        for (int i = chars.length - 1; i >= 0; i--) {
            int tmp = chars[i]-64;
            value+=(tmp*pos);
            pos*=26;
        }
        return value;
    }
相關文章
相關標籤/搜索