小、B最近对电子表格产生了浓厚的兴趣,她觉得电子表格很神奇,功能远比她想象的强大。她正在研究的是单元格的坐标编号,她发现表格单元一般是按列编号的,第1列编号为A,第2列为B,以此类推,第26列为Z。之后是两位字符编号的,第27列编号为AA,第28列为AB,第52列编号为AZ。之后则是三位、四位、五位……字母编号的阿萨德,规则类似。
十大a
表格单元所在的行则是按数值从1开始编号的,表格单元名称则是其列编号和行编号的组合,如单元格BB22代表的单元格为54列中第22行的单元格。
小B感兴趣的是,编号系统有时也可以采用RxCy的规则,其中x和y为数值,表示单元格位于第x行的有第y列。上述例子中的单元格采用这种编码体系时的名称为R22C54。
小B希望快速实现两种表示之间的转换,请你帮忙设计程序将一种方式表示的坐标转换为另一种方式。
思路:
1. 判断是这两种哪种形式,将对应的列使用除基取余的形式去转换。
2. 如何判断,考虑的是根据字符串的个数,第一种划分后字符串的个数是2,数字也是2,第二种是1 1 ,使用正则表达式将具体的数字和字符串分开(刚开始考虑的是根据rc这种字符串的特点,然后去根据index取值....)
- anyway, 正则表达式方便一点 只是不太好记 那这里记一下 String[] strs = string.replaceAll([^0-9]," ").trim().split("\\s+"); 将任意的0-9替换成空格,trim 去除首尾括号 ,按空格分开 包含连续空格。 .. 嗯.....
3. 然后转换完拼接起来 。 我的好像比较慢.. 总之渣渣。
package saima;
import java.util.Scanner;
public class bianHaoConvert {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
while(n>0){
n--;
String s = sc.next();
String[] strs = s.replaceAll("[^A-Z]"," ").trim().split("\\s+"); // 使用一个或多个空格分割
String[] numbers = s.replaceAll("[^0-9]"," ").trim().split("\\s+"); // ^ 任意不是0 的变为空格
if(numbers.length == 2){ // 第-种情况 转变为第二种
int line = Integer.parseInt(numbers[1]);
StringBuilder sb = new StringBuilder();
while(line > 0){
char now;
if(line % 26 == 0){ // 所以为了防止往下减 应该将26的情况单独处理
now = 'Z';
line = line/26 - 1;
}else{
now = (char)( line % 26 - 1 + 'A'); //因为这里要减去1 如果line = 26 的话 那么减去1 就是0
line = line/26;
}
sb.append(now);
}
System.out.println(sb.reverse().toString()+numbers[0]);
}else{// 第二种情况
int sum = 0;
for (int i = 0; i < strs[0].length(); i++) {
sum = sum * 26 + (strs[0].charAt(i)-'A'+1);
}
System.out.println("R"+numbers[0]+"C"+sum);
}
}
}
}
其他:
1. 问题
刚开始没有考虑line = 26的倍数 的情况 只想着line 不可能为0 程序没问题。但是如果是26的倍数,后面char c 就会变成 -1+‘A’ 是符号@ 用例ac 83.3% 所以应对其特殊判断,并且该种情况下 继续的时候line = line/26 -1 而不是26 ,以z 为例,若不减去1 line = 1 那么后面还会有一个A 是错误的
2. 对于数字转string ,用了个stringbuffer 去 reverse。 可以使用直接加? s = ch + s; 反向加 。。。对于短长度的好像影响不大
3. 巡行
想想记不住正则表达式怎么办:
- 遍历一遍 看看 是不是同时符合第一种格式(第一个为R第二个为数字且后面还包含C) 直接substring
- 第二种 取得连续的字符串 放到1个string里 剩下的就是数字 然后计算....