题目
B. Spreadsheets
time limit per test10 seconds
memory limit per test64 megabytes
inputstandard input
outputstandard output
In the popular spreadsheets systems (for example, in Excel) the following numeration of columns is used. The first column has number A, the second — number B, etc. till column 26 that is marked by Z. Then there are two-letter numbers: column 27 has number AA, 28 — AB, column 52 is marked by AZ. After ZZ there follow three-letter numbers, etc.
The rows are marked by integer numbers starting with 1. The cell name is the concatenation of the column and the row numbers. For example, BC23 is the name for the cell that is in column 55, row 23.
Sometimes another numeration system is used: RXCY, where X and Y are integer numbers, showing the column and the row numbers respectfully. For instance, R23C55 is the cell from the previous example.
Your task is to write a program that reads the given sequence of cell coordinates and produce each item written according to the rules of another numeration system.
Input
The first line of the input contains integer number n (1 ≤ n ≤ 105), the number of coordinates in the test. Then there follow n lines, each of them contains coordinates. All the coordinates are correct, there are no cells with the column and/or the row numbers larger than 106 .
Output
Write n lines, each line should contain a cell coordinates in the other numeration system.
Examples
input
2
R23C55
BC23
output
BC23
R23C55
题目理解
题目提供了两个用于表示Excel表中表格位置的方式,一种是我们在office、WPS中常见的,以大写字母表示行的位置,用数字表示列的位置,其中大写字母从A到Z分别表示1~26,当超过26后,则用两个字母表示,如27表示为AA,当需要表示的数已经无法用两个字母即ZZ表示的时候,则增加一个字母进行表示。另一种方式是使用R和C表示行数或者列数,在R/C后面用数字表示所在行/列数。题目的要求就是在这两种表达方式之间进行转换。
解题思路
1、判断属于哪一种表达方法;
2、对现有表达方式进行转换,其中两种方法的列数都是由数字进行表示,故实际上只需要在行数上进行变动,题目就可以理解为是字母字符串与其表示的数字之间的转换,类似于十进制与类26进制之间的转换。
2.1、字符串转为数字:
遍历字符串,获取当前字母在二十六字母中的位置a1,加上前面子字符串计算所得的数ans‘乘以26,即ans = a1+ ans’*26 。最终获得转换后的数字
2.2、数字转为字符:
将数字对26取模,获得所对应字符串在当前位置的字母在二十六个字母中的位置,获取当前位置的字母,然后将数字除以26,进行前一个位置的计算,知道数字变为0。
代码如下(python)
import re
n = int(input().strip())
a = re.compile(r'\bR([\d]+)C([\d]+)')
alp = 'ZABCDEFGHIJKLMNOPQRSTUVWXY'
alp1 = '0ABCDEFGHIJKLMNOPQRSTUVWXYZ'
while n :
n-=1
cnt=input().strip()
if re.match(a,cnt):
r,c = map(int,re.split('\D',cnt)[1:])
ans = ''
while c:
ans = alp[c%26] + ans
c = c//26
if ans[0] == 'Z':
c -= 1
print("%s%d"%(ans, r))
else:
c = map(str, re.split('\d', cnt)[0])
r = re.split('\D', cnt)[-1]
ans1 = 0
for i in c:
ans1 = alp1.index(i) + ans1*26
print('R%sC%d'%(r,ans1))
代码解析
import re
使用正则化库,对提供的字符串进行匹配判断,判断属于哪种表达方式
a = re.compile(r'\bR([\d]+)C([\d]+)')
re.compile() compile() 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 函数使用。
其中的r是防止字符转义的,声明后面的字符串是普通字符串,相对的,特殊字符串中含有:转义字符 \n \t 什么什么的。
其中的 \b 表示匹配一个单词边界,也就是指单词和空格间的位置,如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
其中的 \d 表示匹配任意数字。
[re] 用来表示一组字符,单独列出。
re+ 表示匹配1个或多个的表达式。
这行代码是用来匹配用RC中间后面加数字的表示方法的字符串,与另一种方法区别开来。(r’\bR([\d]+)C([\d]+)’) 表示首个字符为R,然后是一串长度大于等于1的数字,加上一个C,最后也是一串大于等于1的数字。
注: 正则表达式中有一种表达式 re* 为什么不能在这里使用,因为他表示的是长度大于等于0的表达式,当使用这个的时候,会出现匹配出错,当R后面接上C的时候也会成功匹配,但这种“RC”开头的,是属于另一种方法。
alp = 'ZABCDEFGHIJKLMNOPQRSTUVWXY'
alp1 = '0ABCDEFGHIJKLMNOPQRSTUVWXYZ'
alp用于处理RC中间后面加数字的方法的转换,对26取模后的值则是对应字母的下标。
alp1用于处理另一种方法的转换,每个字母的下标即为所需对应的数字。
r,c = map(int,re.split('\D',cnt)[1:])
re.split() split 函数按照能够匹配的子串将字符串分割后返回列表。
这行代码中,从下标为1开始计算的原因是,分割时,将前面的空字符也当成一个子串分割了。
if ans[0] == 'Z':
c -= 1
这里判断当前位置的字母是否为“Z”,如果是则c减去1的原因是,当此时的字母为Z的时候,有一个类似于进位的东西出现了,所以需要减去1。比如26,对应的字母为Z,但是当26除以26时,答案是1,会导致结果变成‘AZ’(对应数字为52),所以需要减去1。