编号转换(百度2016实习生真题)--java

http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3821&konwledgeId=40

编号转换(百度2016实习生真题)

                                题目描述

小B最近对电子表格产生了浓厚的兴趣,她觉得电子表格很神奇,功能远比她想象的强大。她正在研究的是单元格的坐标编号,她发现表格单元一般是按列编号的,第1列编号为A,第2列为B,以此类推,第26列为Z。之后是两位字符编号的,第27列编号为AA,第28列为AB,第52列编号为AZ。之后则是三位、四位、五位……字母编号的,规则类似。

表格单元所在的行则是按数值从1开始编号的,表格单元名称则是其列编号和行编号的组合,如单元格BB22代表的单元格为54列中第22行的单元格。

小B感兴趣的是,编号系统有时也可以采用RxCy的规则,其中x和y为数值,表示单元格位于第x行的有第y列。上述例子中的单元格采用这种编码体系时的名称为R22C54。

小B希望快速实现两种表示之间的转换,请你帮忙设计程序将一种方式表示的坐标转换为另一种方式。

输入
输入的第一行为一个正整数T,表示有T组测试数据(1<=T<=10^5)。随后的T行中,每行为一组测试数据,为一种形式表示的单元格坐标。保证所有的坐标都是正确的,且所有行列坐标值均不超过10^6。
样例输入
2
R23C55
BC23

输出
对每组测试数据,单独输出一行,为单元格坐标的另一种表示形式。
样例输出
BC23
R23C55

时间限制
C/C++语言:1000MS其它语言:3000MS
内存限制
C/C++语言:65536KB其它语言:589824KB

import java.util.Arrays;
import java.util.Scanner;

/**
 * http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3821&konwledgeId=40
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int next = in.nextInt();
        in.nextLine();
        while(next-->0) {
            System.out.println(result(in.nextLine().trim()));
        }
    }

    public static String result(String str) {
        if(str.matches("^R\\d\\d*C\\d\\d*")) {
            return rxcyToBc23(str);
        }else {
            return bc23ToRxcy(str);
        }
    }

    public static String bc23ToRxcy(String bc23) {
        StringBuilder rxcy = new StringBuilder();
        String rx = bc23.split("\\d")[0];
        String cy = bc23.substring(rx.length());
        rxcy.append('R').append(cy).append('C').append(toNum(rx));
        return rxcy.toString();
    }

    /**
     * 第1列编号为A,第2列为B,以此类推,第26列为Z。
     * 之后是两位字符编号的,第27列编号为AA,第28列为AB,
     * 第52列编号为AZ。之后则是三位、四位、五位……字母编号
     * 将编号转为列数
     * @param id
     * @return
     */
    private static int toNum(String id) {
        char[] rx = new char[id.length()+1];
        final char zero = 'A'-1;
        rx[0] = zero;
        //将Z转为A_zero
        for(int i = rx.length-1;i>0;i--) {
            char c = (char) (id.charAt(i-1)+rx[i]);
            if(c=='Z') {
                c = zero;
                rx[i-1] = (char) (rx[i-1] + 1);
            }
            rx[i] = c;
        }
        //将zero、A~I 转为0~9
        //将J~Y转为A~Z
        for(int i=0;i<rx.length;i++) {
            char c = rx[i];
            if(c-zero>=10) {
                c = (char) (c-9);
                rx[i] = c;
            }else {
                rx[i] = (char) (c-zero+'0');
            }
        }
        return Integer.parseInt(new String(rx),26);
    }

    /**
     * 将列数转为编号
     * @param num
     * @return
     */
    private static String toId(int num) {
        //将num转为26进制
        String num26 = Integer.toString(num, 26).toUpperCase();
        final char zero = 'A'-1;
        //将num转为zero、A~Y
        char []id = new char[num26.length()];
        for(int i = 0;i<id.length;i++) {
            char c = num26.charAt(i);
            if(c<='9') c = (char) (c+zero-'0');
            else c = (char) (c + 9);
            id[i] = c;
        }
        //将?_zero转为?-1_Z
        for(int i = id.length-1;i>0;i--) {
            if(id[i]<=zero) {
                id[i] = (char) (id[i]-zero+'Z');
                id[i-1]--;
            }
        }
        //判断是否产生退位
        if(id[0]==zero)
            id = Arrays.copyOfRange(id, 1, id.length);
        return new String(id);
    }

    public static String rxcyToBc23(String rxcy) {
        int index = rxcy.indexOf('C');
        String rx = rxcy.substring(1,index);
        String cy = rxcy.substring(index+1);
        return toId(Integer.parseInt(cy))+rx;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值