3

我正在尝试使用 JExcel 重新排序一些 Excel 列。我还需要找到对其他单元格的引用,然后重新映射它们以引用正确的单元格。我觉得我做了很多艰苦的工作,但我遇到了一个绊脚石。

我在wikipedia上找到了这段代码,链接到 SO:

 public static String toBase26(int number){
        number = Math.abs(number);
        String converted = "";
        // Repeatedly divide the number by 26 and convert the
        // remainder into the appropriate letter.
        do
        {
            int remainder = number % 26;
            converted = (char)(remainder + 'A') + converted;
            number = (number - remainder) / 26;
        } while (number > 0);

        return converted;
    }

但是当我在其中运行数字 35 时,会发生以下情况:

  1. number= 35
  2. remainder= 9
  3. converted= 字符(9+'A')+"" = J
  4. number= (35-9)/26 = 1
  5. 1>0
  6. remainder= 1
  7. char(1+'A')= B
  8. converted= 字符(1+'A')+"J" = BJ

以某种预期的方式,即 Base 10 (35) = Base 26 (19)。但我实际上想参考 AJ 栏。

我无法弄清楚我需要做哪些改变才能得到正确的字母。每当我试图在纸上解决它时,我最终都会毁掉之前提取的字母。例如,我认为行不通,因为这意味着我remainder第一次以 8 结束,然后将转换为 I,除非我错过了什么?

对此的任何帮助将不胜感激。我环顾四周并在这上面浪费了足够的时间。我只是想要一些帮助来让它工作。

4

2 回答 2

5

这个“十六进制系统”背后的绊脚石是它有一个 0,但单位列跳过了 0 并且范围仅从 AZ 开始。考虑以下十进制转换:

A 1 (0*26 + 1)
...
Z 26 (0*26 + 26)
AA 27 (1*26 + 1)
...
AZ 52 (1*26 + 26)
BA 53 (2*26 + 1)
...
BZ 78 (2*26 + 26)
CA 79 (3*26 + 1)
...
ZZ 702 (26*26 + 26)
AAA 703 (1*26*26 + 1*26 + 1)

看到问题了吗?十六进制数字中缺少“零”:

00A 1
...
00Z 26
0AA 27
...
0AZ 52
0BA 53
...
0BZ 78
0CA 79
...
0ZZ 702 (26*26 + 26)
AAA 703 (1*26*26 + 1*26 + 1)

但是,单位列从来没有零!

显然我们不会打印这些零,但它应该有助于您了解出了什么问题。


这是我们的算法。我在十进制 0 = 十六进制 A、1 -> B、25 -> Z、26 -> AA 等假设下编写算法,因为它让我更容易理解。如果这不是您想要的假设,只需在运行代码之前减去 1 :)

0. If number =< 0, return.

1. Modulo by 26. Convert 0-25 to 'A'-'Z'. //This is our units column.

Loop {

    2. Divide the number by 26 (integer division rounding down).

    3. If number =< 0, return.

    4. Modulo by 26. Convert 0-25 to 'Z','A'-'Y'. //This is our next column (prepend to string output).

} 

例子

转换十进制 730 -> ABC 十六进制

以 730 为模乘以 26 = 2 -> 'C' 表示单位列

730 除以 26 = 28

模 28 x 26 = 2 -> 'B' 十列

28 除以 26 = 1

模 1 乘 26 = 1 -> 'A' 表示数百列

将 1 除以 26 = 0

数字为空,因此返回 'ABC'

于 2013-04-24T11:19:07.383 回答
4

这是一个简单的 Python 函数,用于计算数字的十六进制表示(以任意基数),其中a等于1(not 0)。

问题的棘手部分是,在每一步中,您都在其余部分之间1进行10取舍,因此您需要在模数中考虑到这一点。1下面的代码通过每次从数字中减去来解释它。然后0成为一个非常方便的结束条件,因为你不能0用十六进制表示(维基百科条目表示它λ)。

# Formats a number as a bijective base N string.
def bijective(n, base):
  chars = ''
  while n != 0:
    chars = chr((n - 1) % base + 97) + chars
    n = (n - 1) / base

  return chars

# Examples!
if __name__ == '__main__':
  base = 26
  for n in range(1, 2 * base * base):
    print('{}: {}'.format(n, bijective(n, base)))

在pythonanywhere上查看它的实际效果。

我在这个要点中包含了一个 javascript 版本。

于 2016-01-05T06:16:00.113 回答