簡體   English   中英

如何將整數轉換為 A1 表示法?

[英]How can I convert an integer to A1 notation?

我正在嘗試創建一種方法,可以在給定列之后找到下一列。 例如:

input: A
output: B

乍一看似乎很簡單。 我只是打算使用以下方法:

public static char nextLetter(char c) {
    c++;
    return c;
}

當你越過 Z 列時就會出現問題。在 Google 表格中,在 Z 列之后,列名是兩個字母,然后是三個字母,等等。所以在Z列之后是AA ,在AZ之后是BA ,在ZZ之后是AAA等等。我的下一個想法是首先根據索引找出列位置。 因此, AA列將是 27、 BA 52 等。

查找列的索引不是我現在面臨的問題。 我需要弄清楚如何將該索引轉換為相應的列名。 我打算嘗試以下方法,但我意識到它也僅限於 AZ:

public static char getLetter(int index) {
    return (char) (index + 64);
}

在這一點上,我認為需要一種遞歸方法。 但是,我無法弄清楚如何設置它。 這是我得到的:

private static void getNotation(int size) {
    int divided = size / 26;
    int remainder = size % 26;

    String notation = "";

    while (divided % 26 > 0) {
        // Here is where the need for a recursive method comes in
    }

}

有誰知道將整數(索引)轉換為相應列名的好方法嗎?

編輯

我剛剛在 Github 上找到了一個非常有用的資源,它處理了十六進制: https ://gist.github.com/pinguet62/9817978

我創建了一個示例:

class Test {
    static char[] alphabet = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
                               'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
                               'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

    private static String indexToColumnName(int i) {
        if (i >= alphabet.length) {
            return indexToColumnName((int)Math.floor(i / alphabet.length) - 1)
              + indexToColumnName(i % alphabet.length);
        }
        return Character.toString(alphabet[i]);
    }

    public static void main(String args[]) {
        for (int i = 0; i <= 800; ++i) {
            System.out.println(i + ": " + indexToColumnName(i));
        }
    }
}

以上將產生類似的東西:

0: A
1: B
2: C
3: D
...
24: Y
25: Z
26: AA
27: AB
...
700: ZY
701: ZZ
702: AAA
703: AAB
...

在這種情況下,它是零索引,但您可以輕松更改自己。

嘗試一下

private static String getNotation(int size) {
        String result = "";
        int q = 0; // How many characters does the notation consist of?
        int f1 = 0;
        int f2 = 0;
        while (f2 < size) {
            q += 1;
            f1 = f2;
            f2 += Math.pow(26, q);
        }

        size -= f1;
        size--;
        for (int i = 0; i < q; i++) {
            result = (char) (size % 26 + 65) + result;
            size /= 26;
        }

        return result;
    }

我想像六進制(基數 16),你可以使用基數 26。可以嘗試使用基數 10 到基數 X 轉換器。 主要問題是,在這種情況下,在“數字”“Z”之后你有數字“AA”,就像在數字 9 之后你將有 00。或者在六進制中,如果在 F 之后你有 00 而不是 10。

我自己嘗試了很多,但終於找到了這個主題: 如何將列號(例如 127)轉換為 excel 列(例如 AA)

在 Java 中:

private static String getNotation(int size) {
    str = "";
    int r;
    while(size >0) {
        r = (size-1) % 26;
        str = getLetter(r+1)+ str;
        size = (size-r) /26 ;
    }
    return str;
}

似乎解決方案只是模數附近的 -1,如果刪除它,您會將 A 視為 0,因此在 Z 之后將有 BA 之類的十進制到基數 26 轉換器。

你可以這樣做:

public class Main {
    public static void main(String[] args) {
        System.out.println(getNextColumn("A"));
        System.out.println(getNextColumn("Z"));
        System.out.println(getNextColumn("AA"));
        System.out.println(getNextColumn("AZ"));
        System.out.println(getNextColumn("ZA"));
        System.out.println(getNextColumn("ZZ"));
        System.out.println(getNextColumn("AAA"));
        System.out.println(getNextColumn("ABA"));
        System.out.println(getNextColumn("ABZ"));
        System.out.println(getNextColumn("ZZZ"));
    }

    static String getNextColumn(String column) {
        column = column.toUpperCase();
        StringBuilder sb = new StringBuilder();
        boolean allZ = true;
        for (int i = 0; i < column.length(); i++) {
            if (!(column.charAt(i) == 'Z')) {
                allZ = false;
                break;
            }
        }
        if (allZ) {
            for (int i = 0; i <= column.length(); i++) {
                sb.append('A');
            }
            return sb.toString();
        }
        boolean charAfterZ = false;
        int indexOfZ = 0;
        for (int i = 0; i < column.length() - 1; i++) {
            if (column.charAt(i) == 'Z') {
                charAfterZ = true;
                indexOfZ = i;
                break;
            }
        }
        if (charAfterZ) {
            sb.append(column.substring(0, indexOfZ + 1) + (char) (column.charAt(indexOfZ + 1) + 1));
            if (column.length() > indexOfZ + 2) {
                sb.append(column.substring(indexOfZ + 1));
            }
            return sb.toString();
        }

        char lastChar = column.charAt(column.length() - 1);

        if (lastChar == 'Z') {
            sb.append(column.substring(0, column.length() - 2) + (char) (column.charAt(column.length() - 2) + 1) + ""
                    + 'A');
        } else {
            if (column.length() > 1) {
                sb.append(column.substring(0, column.length() - 1) + ""
                        + (char) (column.charAt(column.length() - 1) + 1));
            } else {
                sb.append((char) (column.charAt(column.length() - 1) + 1));
            }
        }
        return sb.toString();
    }
}

輸出:

B
AA
AB
BA
ZB
AAA
AAB
ABB
ACA
AAAA

有點晚了,但昨天我需要在 Go 中將整數轉換為 A1 表示法,所以我做了這個遞歸函數:

func indexToA1Notation(column int) string {
    if column <= 'Z'-'A' {
        return string(rune('A' + column))
    }
    return fmt.Sprintf("%s%s", indexToA1Notation((column/26)-1), string(rune('A'+column%26)))
}

我知道,Go 不是 Java,但它可以輕松移植(我曾經在 Java 中工作過很多)。

編輯:好的,我花時間移植了它

  public static String indexToA1Notation(int column) {
    if (column <= 'Z' - 'A') {
      return Character.toString('A' + column);       
    }
    return String.format("%s%s", indexToA1Notation((column/26)-1), Character.toString('A'+column%26));
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM