目录
=========================================================================
题目
Excel是最常用的办公软件,每个单元格都有唯一的地址表示,比如:第12行第4列表示为:“D12”第5行第255列表示为“IU55”。
事实上,Excel提供了两种地址表示方法,还有一种表示叫做RC格式地址。
第12行第4列表示为:“R12C4”,第5行第255列表示为“R5C255”。
你的任务是:编写程序,实现从RC地址格式到常规地址的转换。
【输入,输出格式要求】
用户先输入一个整数n(n<100),表示接下来有n行输入数据。
接着输入的n行数据是RC格式的Excel单元格地址表示法。
程序则输出n行数据,每行是转换后的常规地址表示法。
例如:用户输入:2
R12C4
R5C255
则程序应该输出:
D12
IU5
俗话说:“心急吃不了热豆腐”
俗话也说:“一口吃不成个胖子,一步到不了天边。”
----不管是什么都要慢慢来,不能急于求成。
输入数据
关于上面的题我们可以一步一步来,首先解决我们的输入问题(以下是我的思路,各有各的想法,只做参考):
- 先输入一个数字表示我们接下来要输入的数据行数
- 将我们输入的数字作为循环语句的结束条件来控制我们输入的数据行数
- 输入的数据还只是个字面值,不是一个被保存的数据,因此我们要将输入的数据放入一个变量中来进行保存,以便后期将数据打印出来给用户查看
Scanner sc=new Scanner(System.in);
System.out.println("请输入行数:");
int num_input=sc.nextInt();
int i=0;
String str_start="";
while(i<num_input) {
Scanner sc1=new Scanner(System.in);
System.out.printf("请输入第%d行数据(按enter键结束输入):\n",i+1);
String str_input=sc1.nextLine();
str_start+=(str_input+"\n");
i++;
}
System.out.println("您输入的数据为:\n"+str_start);
上面其实还有一个不足,就是当我们输入的字母不是大写字母,而是a~z时,就会影响到我们后期ASCII码的计算,在计算机中A的ASCII码为65,而a为A的ASCII码+32,即97。
我们的程序就需要提示给用户:输入的字母为小写,并对输入的数据进行修改,之后再将其加入到我们的变量中。
if(str_input!=str_input.toUpperCase()) {
System.out.println("您输入的RC引用样式不正确,已为您转换成大写\n"+str_input.toUpperCase());
}
str_start+=(str_input.toUpperCase()+"\n");
i++;
}
如果有兴趣想要了解字符串相关知识的,欢迎访问博客:java中的字符串处理
字符转换
前期excel知识储备
因为我们之前输入了行数,以及相应行数的数据。所以接下来我们需要做的就是将输入的输入转据(RC引用样式表示的单元格)换成对应的(A~Z,AA~AZ,ZA~ZZ引用样式表示的单元格格式)。
储备:相信用过excel的都熟悉R2C4表示的是什么意思,即第2行第4列。我们的这种样式只是Excel的单元格引用两种样式中的一种,即RC引用样式,接下来我们来对Excel的单元格引用的两种样式做一个了解:
- 常见的A1引用样式,即列标+行号的表示方式,比如B3是B列第3行。
- R1C1引用样式,即R+行号+C+列号的表示方式,字母R表示row,行的意思,字母C表示column,列的意思。比如R5C2表示第5行第2列,也就是B5单元格。
RC样式的只需要注意行和列的数即可,而A~Z,AA~AZ,...........ZA~ZZ样式的还得需要注意列的表示,如果是26以内的,则使用单个字母,从A到Z,而如果超过了26,但是没有到51的话则使用AA~AZ,并以此类推。
中期计算逻辑
将字符串里面的RC字母去掉

从上面我们可以看到产生的新字符串虽然没有了字母,但是开头的‘,’逗号却是我们不想要的,这个时候大家想到了什么方法来去掉前面的逗号呢?
大家可以按照自己的喜欢来进行处理,这里我就拿我的方法来去掉,我们可以使用subString来选取字符串的内容元素来生成一个新的字符串,如下:

到这一步的时候其实已经差不多得到一个没有字母的字符串了。接着我们将换行的形式修改成一行的形式进行显示。这个时候我们可以继续使用replace方法将换行符替换成‘’空字符串。

字符串的处理其实局限还是挺多的,它的遍历没有数组来得方便,,因此我们可以先使用split方法将字符串转成数组,再进行遍历

观察数字所在位置规律
由上图我们可以看列对应的位置下标为:1,3。可以推测出第三行的数据列数为5。即an=2n-1。
行对应的位置下标为:0,2。可以推测出第三行数据行数为4。即an=2n。


如上我们将每行数据的行列位置进行了交换。接下来我们将前面的列数转换成字母
字符数字转ASCII码,再转字母

之后我们不将得到的字母放到字符串中,而是让其替换数组里面的列下标位置的数字。

之后我们将左边为字母,右边为数字所夹的逗号去掉。

之后让结果换行输出

看起来我们似乎已经完成了,但是还有一点我们需要考虑就是在excel表中,如果我们的数字大于26但是小于51的话就需要使用AA-AZ,【52~77,BA~BZ..........】
当我们的列数为255时,对应的常规样式表示的值为IU.

并且可知A,AA....IA之间的关系,以及IA到IU相差几个字母。

结合下图,我们可以知道一个列数超过26,但是还是在26*26范围内的数字就可以使用:num/26的方法得到我们的对应字母。
现在我们需要考虑的就是取到算式结果的商和余数。
- 商可以使用整除的方法,即num/26
- 余数可以使用取模的方法,即num%26
因此我们的程序可以进行如下修改

修改后如下:

后期结果呈现及代码整理
效果

代码:
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.text.html.parser.Parser;
public class Transform_lq {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.print("请输入行数:\n");
int num_input=sc.nextInt();
int i=0;
String str_start="";
while(i<num_input) {
Scanner sc1=new Scanner(System.in);
System.out.printf("请输入第%d行数据(按enter键结束输入):",i+1);
String str_input=sc1.nextLine();
if(str_input!=str_input.toUpperCase()) {
System.out.println("您输入的字母为小写,已为您转换成大写格式\n"+str_input.toUpperCase());
}
str_start+=(str_input.toUpperCase()+"\n");
i++;
}
System.out.println("您输入的数据为:\n"+str_start);
String str_reg="[R,C]";
Pattern pattern = Pattern.compile(str_reg);
Matcher matcher=pattern.matcher(str_start);
String str_new1="";
while(matcher.find()) {
str_new1=str_start.replaceAll(str_reg, ",");
}
String str_new=str_new1.substring(1,str_new1.length());
String str_new2=str_new.replace("\n","");
String[] str_new_arr=str_new2.split(",");
int c=1; //列的初始位置
int r=0; //行的初始位置
// System.out.println(Arrays.toString(str_new_arr));
for(int i1=0;i1<str_new_arr.length;i1++) {
if(c <str_new_arr.length && r <str_new_arr.length) {
String s=str_new_arr[r]; //行的位置先存放到字符串变量中
str_new_arr[r]=str_new_arr[c]; //列的位置提到行前
str_new_arr[c]=s; //行的位置
r+=2; //自增2
c+=2;
}
}
// System.out.println(Arrays.toString(str_new_arr));
for(int i1=0;i1<str_new_arr.length;i1+=2) { //遍历的是列数据
if(Integer.parseInt(str_new_arr[i1])<=26) {
int num=Integer.parseInt(str_new_arr[i1])-1+'A'; //得到当前列字符数字对应的ASCII码
str_new_arr[i1]=numIntoLetter(num); //创建了一个方法来转换整数
}else {
int num=Integer.parseInt(str_new_arr[i1]);
int zheng=num/26;
int yu=num%26;
//将数字转换成对应的字母
int c_zheng=zheng+'A'-1; //整数
int c_yu=yu+'A'-1; //余数
str_new_arr[i1]=(numIntoLetter(c_zheng)+numIntoLetter(c_yu));//当列数大于26时
}
}
// System.out.println(Arrays.toString(str_new_arr));
String s="";
for(int i1=0;i1<str_new_arr.length-1;i1+=2) {
if(i1+1!=str_new_arr.length-1) { //判断末尾下标的位置
s+=str_new_arr[i1]+str_new_arr[i1+1]+",";
}
else {
s+=str_new_arr[i1]+str_new_arr[i1+1]; //末尾不加‘,’
}
}
String s1=s.replace(",", "\n"); //换行输出
System.out.println("数据结果输出:\n"+s1);
}
//方法:将数字字符串数字转换成字母
public static String numIntoLetter(int i) {
Character c=(char)i; //将ASCII码转字符
return c.toString(); //将字符转字符串字母
}
}
有问题的请在评论区留言,会在36小时内回复。
这篇博客详细介绍了如何从Excel的RC格式地址转换为常规的A1格式地址,包括输入处理、ASCII码转换和逻辑计算等步骤。通过示例代码解析了转换过程,涉及字符串操作、数字与ASCII码的相互转换等技巧。

141

被折叠的 条评论
为什么被折叠?



