java题excel地址,[Java] [刷题] Excel地址转换

题目

将一个整数转换为Excel的列号,整数范围为[1, 2147483647]。

Excel的单元格中,列号表示如下:

A表示第1列,

B表示第2列,

Z表示第26列,

AA表示第27列,

AB表示第28列,

BA表示第53列,

……

I/O

样例1

样例2

输入

26

2054

输出

Z

BZZ

来源

蓝桥杯2012年高职高专组JAVA组 决赛第4题

蓝桥杯2012年高职高专组C语言组 决赛第3题

解题思路

从题目附加描述中的“列号”可以看出,这一题应该用“进制转换”的解法,即除n求余倒插(n为进制数),但这题的坑在于——Excel的列号没有0!

十六进制符号有0到F十六个,分别代表0到15;Excel列号的符号有A到Z二十六个,按描述来说分别代表1到26,显然没有0。没有0的话不能按常规进位制算法处理,于是在前期将A到Z对应成0到25,再在后期“+1”,对应回原来的1到26。

假设在前期的处理中,A对应0,Z对应25,那么Z+1(即25+1==26)对应什么呢?再进一步,假设此时存在列号“AA”,那么它的两个A是代表十进制数的0还是1呢?

那么对题目附加描述进行分析,可以得到下表:

列号

十进制数

分解算式

分解算式++

A

1

1

26 * 0 + 1 * 1

B

2

2

26 * 0 + 1 * 2

AA

27

26+1

26 * 1 + 1 * 1

AB

28

26+2

26 * 1 + 1 * 2

BA

53

52+1

26 * 2 + 1 * 1

按照正常进制算法用短除法分析样例中的2054,得到

2054 == 676*3 + 26*1 + 1*0,对照ASCII表得到的CA@或DBA都是错的。

因为Excel的列号没有0,于是按照进位制的思想向前借一,得到

2054 == 676*3 + 26*0 + 1*26,仍然有0。

于是再向前借一,得到

2054 == 676*2 + 26*26 + 1*26,对照ASCII表得到BZZ,正确!

我的实现

package top.qlin.leo;

import java.util.Scanner;

public class Main {

/** ASCII表中字符A的前一个字符,代表进位制中的0。用于判断分解的结果中是否有0。 */

final static char FLAG = 'A' - 1;

public static void main(String[] args) {

// 使用Scanner从输入流中获取等待被转换为Excel的整数num:

Scanner sr = new Scanner(System.in);

int num = sr.nextInt();

sr.close();

// 为了提升效率,使用StringBuffer存放结果:

StringBuffer n26bf = new StringBuffer();

// N进制转十进制的算法:

// 将整数num除以二十六进制的进制数26,将余数转换为字母,插入到StringBuffer的位置0中(即先出现的余数放到结果的右端,后出现的余数放到左端);将商作为整数num送入下一循环再次运算。

while (num > 0) {

n26bf.insert(0, (char) ((num % 26) + 64));

num /= 26;

}

// 将结果转换为字符数组:

char[] n26cs = n26bf.toString().toCharArray();

// 从结果的右端(最后一位数)循环遍历到左端(第二位数),若有0则向前借一:

for (int i = n26cs.length - 1; i > 0; i--) {

if (n26cs[i] == FLAG) {

n26cs[i] += 26;

n26cs[i - 1]--;

}

}

// 借位完毕后,如果第一位为0,则只需从第二位开始输出。

if (n26cs[0] == FLAG) {

System.out.print(String.valueOf(n26cs).substring(1, n26cs.length));

} else {

System.out.print(String.valueOf(n26cs));

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值