为什么“ col”变量返回错误值

多臂

在最近的一次面试中,我不得不解决一个程序性问题。问题是将给定的excel字母列名称转换为列号。在他们(采访者)给我“ AUHS”作为列名之前,我的解决方案大部分时候都起作用。解决方案破裂了。预期答案为“ 31999”,但我得到“ 18999”。我想了解哪里出了问题以及如何改进解决方案。

PS:我是Java新手

我的解决方案

public class test {

    public static void main(String[] args) {
        String argChar = "AUHS";

        char a = 'A';
        int asciiA = (int) a;

        int col = 0;
        col += Math.pow(26, 0) + (int)argChar.charAt(argChar.length()-1) - asciiA;

        for(int i=1; i<argChar.length(); i++) {
            col += (int)(Math.pow(26, i) + ((int)argChar.charAt(argChar.length()-(i+1)) - asciiA) * 26);
        }

        System.out.println(col);

    }
}
hc_dev

电子表格的字母列标签的公式

AZ编码的(base-26)列标签的序列为:

A .. 1 (= 26^0*1)
B .. 2 (= 26^0*2)
H .. 2 (= 26^0*8)
S .. 2 (= 26^0*19)
U .. 2 (= 26^0*21)
Z .. 26 (= 26^0*26)

AA .. 27 (= 26^1*1 +1)
AZ .. 52 (= 26^1*1 +26)  
BA .. 53 (= 26^1*2 +1)
ZZ .. 702 (= 26^1*26 +26)

AAA .. 703 (= 26^2*1 + 26^1*1 + 26^0*1)
UHS .. 14423 (= 26^2*21 + 26^1*8 + 26^0*19)
AUHS .. 31999 (= 26^3*1 + 26^2*21 + 26^1*8 + 26^0*19)

因此我们可以将公式(用伪数学符号)推导为:

  sum-of ( 26^index * letterAsNumber ) over each letter
  where index is the position of the letter from the end starting with 0
  where letterAsNumber is the letter mapped to a number {1..26}
  where letter must be in range {A..Z}

另请参见位置符号

Java中此公式的各个部分

给出以下输入:

  • 列标签 String columnLabel
  • 基础 int radix = 26
  • ASCII码偏移量int asciiOffset = 65 - 1A具有十进制ASCII码65

我们需要计算以下工作变量:

  • 向后索引int backwardsIndex,它是初始值0,当遍历每个字符时递增1;从column-label的末尾开始(因此:向后!)
  • 运行的列数long columnNumber,其中一个柱的字母数字字符的表示将每次迭代过程中加入

Java中的公式

    final int asciiOffset = (int) 'A' - 1; // 64 = 65 - 1, so that (int) 'B' - asciiOffset == 2
    long columnNumber = 0;

    for (int backwardsIndex=0; backwardsIndex < columnLabel.length(); backwardsIndex++) {
        char letter = columnLabel.charAt(columnLabel.length() - backwardsIndex -1);
        int letterAsNumber = (int) letter - asciiOffset;
        columnNumber += Math.pow(26, backwardsIndex) * letterAsNumber;
    }

    return columnNumber;
}

请参阅在IDEone上工作的演示

代码中的问题

我向他们展示的内容:

  • 将您的一些陈述分成有意义且可测试的部分
  • 评论了这些问题(实际值和预期值)
  • assert在某些行下面添加了一个(以验证期望值)
  • 在下面添加了一个修复声明(有一些解释)
String argChar = "AUHS";

// int asciiA = (int) 'A'; // actual: 65; expected: 64
int asciiA = (int) 'A' - 1; // should be an offset to have: (int) `A` - offset == 1
assert asciiA == 64;

int col = 0;
char letter = argChar.charAt(argChar.length()-1); // actual == expected: 'S'
int letterAsNumber = (int) letter - asciiA; // actual: 83 - 65: expected: 83 - 64;
assert letterAsNumber == 19;
// col += Math.pow(26, 0) + letterAsNumber; // actual: 20 = 1 + 19; expected: 19 = 1 * 19
col = (int) Math.pow(26, 0) * letterAsNumber; // multiply instead add
assert col == 19;

for(int i=1; i<argChar.length(); i++) {
    letter = argChar.charAt(argChar.length() - (i + 1));
    // letterAsNumber = ((int) letter - asciiA) * 26;
    letterAsNumber = ((int) letter - asciiA); // should not add 26 at the end
    // col += Math.pow(26, i) + letterAsNumber;
    col += Math.pow(26, i) * letterAsNumber; // multiply instead add
}
assert col == 31999;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章