1. 程式人生 > >演算法:根據excel列數計算列號

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

在微軟的5面的時候遇到了一個演算法題,根據excel列號計算列數以及根據列號計算列數,由於面試時候答得不好,因此這裡記錄一下實現思路。


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

思路:

這個題目本質上可以簡化為一個26進位制轉10進位制的題目,那麼思路就很容易了:

    /**
     * 本質上是一個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,改成傳遞的方式即可:

   /**
     * 衍生出其他進位制轉換為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,我們在進行一個根據列號求列數的方式:


   /**
     *
     * @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 v