Java 序列中英文與數字的轉換

遇到一項需求
英文序列:A, B, C … Z, AA, AB … AZ, BA, …
數字序列:1, 2, 3 … 99, 100, 101…

不同序列的編碼要轉換
類似Excel的橫列編號

牽扯到
一、10進位與26進位的轉換。這部分是數學知識。
二、字母與數字的轉換。這是關於 String、char 的知識。

英文轉數字(26進位轉10進位)

程式邏輯:
1. 每個字元個別計算
2. 算出英文字代表的值
3. 乘以26的次方,依照位數遞減
4. 計算和

範例:XIOP
X → 24 * 263 = 421824
I → 9 * 262 = 6084
O → 15 * 261 = 390
P → 16 * 260 = 16
421824 + 6084 + 390 + 16 = 428314

public int letterToNumber(String letter) {
    letter = letter.toUpperCase();
    if (!letter.matches("^[A-Z]+$")) {
        throw new IllegalArgumentException();
    }

    int power = letter.length() - 1;
    int sum = 0;
    for (int i = 0; i < letter.length(); i++) {
        char c = letter.charAt(i);
        int ordinal = c - 64;

        sum += ordinal * Math.pow(26, power);
        power--;
    }
    return sum;
}

測試

System.out.println("A:\t" + letterToNumber("A"));
System.out.println("B:\t" + letterToNumber("B"));
System.out.println("Z:\t" + letterToNumber("Z"));
System.out.println("AA:\t" + letterToNumber("AA"));
System.out.println("AD:\t" + letterToNumber("AD"));
System.out.println("d:\t" + letterToNumber("d"));

數字轉英文(10進位轉26進位)

程式邏輯:
1. 將數字除以26,使用遞迴除到不能除
2. 記錄商與餘數
3. 將商與餘數轉換成對應的英文
4. 拼接字串

範例:428314
428314 / 26 = 16473…16
16473 / 26 = 633…15
633 / 26 = 24…9

24 → X
9 → I
15 → O
16 → P

public String numberToLetter(int number) {
    if (number <= 0) {
        throw new IllegalArgumentException();
    }

    String result = "";
    List<Integer> list = new ArrayList<Integer>();
    count(number, list);
    for (int i : list) {
        char c = (char) (i + 64);
        result += c;
    }
    return result;
}

private void count(int number, List<Integer> list) {
    int quotient = number / 26;
    int remainder = number % 26;
    if (quotient > 26) {
        count(quotient, list);
    } else {
        list.add(quotient);
    }
    list.add(remainder);
}

測試

System.out.println("1:\t" + numberToLetter(1));
System.out.println("2:\t" + numberToLetter(2));
System.out.println("26:\t" + numberToLetter(26));
System.out.println("27:\t" + numberToLetter(27));
System.out.println("30:\t" + numberToLetter(30));