在微軟的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; }