第六届蓝桥杯大赛个人赛省赛(软件类) 【Java 大学C组】格子中输出
格子中输出
类型:占位符的应用
参考:蓝桥杯-格子中输出-java
提示:以下是本篇文章正文内容,下面案例可供参考
问题描述
stringInGrid方法会在一个指定大小的格子中打印指定的字符串。
要求字符串在水平、垂直两个方向上都居中。
如果字符串太长,就截断。
如果不能恰好居中,可以稍稍偏左或者偏上一点。
下面的程序实现这个逻辑,请填写划线部分缺少的代码。
public static void stringInGrid(int width, int height, String s)
{
if(s.length()>width-2) s = s.substring(0,width-2);
System.out.print("+");
for(int i=0;i<width-2;i++) System.out.print("-");
System.out.println("+");
for(int k=1; k<(height-1)/2;k++){
System.out.print("|");
for(int i=0;i<width-2;i++) System.out.print(" ");
System.out.println("|");
}
System.out.print("|");
String ff = _______________________________________________________; //填空
System.out.print(String.format(ff,"",s,""));
System.out.println("|");
for(int k=(height-1)/2+1; k<height-1; k++){
System.out.print("|");
for(int i=0;i<width-2;i++) System.out.print(" ");
System.out.println("|");
}
System.out.print("+");
for(int i=0;i<width-2;i++) System.out.print("-");
System.out.println("+");
}
对于题目中数据,应该输出:
±-----------------+
| |
| abcd1234 |
| |
| |
±-----------------+
(如果出现对齐问题,参看【图1.jpg】)
答案提交
请填写划线部分缺少的代码。
解题思路
这题主要是考拼接字符串,要熟练使用占位符。
参考文档中的答案为"%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-s.length()-2)/2+"s";
参考:https://blog.csdn.net/weixin_30824599/article/details/97733747
注:被格式化的参数索引%1$s和%2$s分别表示第一位和第二位占位符,$s表示是字符串。
参考:https://zhidao.baidu.com/question/630154732789786164.html
也有答案写成"%"+(width-s.length())/2+"s%s%"+((width-s.length())/2-2)+"s"
参考:https://blog.csdn.net/qq_44093986/article/details/87713529
这两个答案在本题中符合条件。(考试时写成这样能拿分就行了。)
不过题目还有(要求字符串在水平、垂直两个方向上都居中。
如果字符串太长,就截断。
如果不能恰好居中,可以稍稍偏左或者偏上一点。)的要求。
上面的其中一个答案在偏左这点上也还达不到要求。
而且把这些答案复制到代码中运行时发现当输入的宽度为奇数时会出现输出少一格的情况。这是因为int在做除法运算((width-s.length())/2)的时候,如果width-s.length()为奇数会把小数点后的数舍掉(int不做浮点运算),本题给width定的变量类型为int。而且代码中的s.substring(0,width-2)也用到了width变量,而substring方法不支持浮点。故不可以把width的整型类型修改为浮点类型。
只能试试在答案中做修改。
修改后的答案为:
"%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"
即前面的
(width-s.length()-2)/2
[(宽-字符串长度-两边的竖线)/2]
不变,后面改成
(width-((width-s.length()-2)/2)-s.length()-2)
[(宽-((宽-字符串长度-两边的竖线)/2)-字符串长度-两边的竖线] =
[(宽-(字符串前面要打印的空格长度)-字符串长度-两边的竖线]
改成这样后不管是偶数还是奇数都能适应。
搭嘎(但是)
当输入的宽度小于字符串长度时,会直接爆炸。
虽然上面的两个参考网页的答案在输入的宽度小于字符串长度时不报错,但一样会出现输出少一格或多一格的情况。
因此在修改过的答案的基础上,再加一个三元运算
参考:java三元运算符
最后修改的答案为:
width>s.length()+2?("%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"):"%s%s%s";
最后这个答案最小宽度可以输入2,
因为输入1时整个代码块中的stringInGrid方法中的第一句
if(s.length()>width-2) s = s.substring(0,width-2);
会报错
原因是substring在截取字符串时,当width为1时,1-2=-1。
substring的截取索引必须>=0;故程序报错。
在不修改原代码块的基础上加上三元运算符的最后答案已经是最接近最优解的答案了。
Java代码
代码如下(示例):
public class NewTest {
public static void main(String[] args) {
stringInGrid(19,6,"abcd1234");
}
public static void stringInGrid(int width, int height, String s)
{
//如果字符串长度大于宽度
//截断字符串。
if(s.length()>width-2) s = s.substring(0,width-2);
System.out.print("+");
for(int i=0;i<width-2;i++) System.out.print("-");
System.out.println("+");
for(int k=1; k<(height-1)/2;k++){
System.out.print("|");
for(int i=0;i<width-2;i++) System.out.print(" ");
System.out.println("|");
}
System.out.print("|");
//String ff = width>s.length()+2?("%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"):"%s%s%s";的意思为:
//当宽度大于(字符串长度+2)时
//把"%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"赋值给ff。
//否则将%s%s%s赋值给ff。
//最后把ff传入到String.format()中,为第一个参数。
//String.format()是一个格式化字符串的方法。这里作拼接字符串用。
//"%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"可以拆分为
//"%1$"+(width-s.length()-2)/2+"s"+"%2$s"+"%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"
//即
//一、"%1$"+(width-s.length()-2)/2+"s"
//二、"%2$s"
//三、"%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"
//三部分
//其中
//一、"%1$"+(width-s.length()-2)/2+"s"在String.format(ff,"",s,"")中的意思为第一位占位符在(width-s.length()-2)/2个空格后拼
//接 System.out.print(String.format(ff,"",s,""));中的String.format()格式化方法中的第二个参数即""。
//二、"%2$s"在String.format(ff,"",s,"")中的意思为第二位占位符在0个空格后拼接第三个参数即变量s。
//三、"%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"在String.format(ff,"",s,"")中的意思为第三位占位符
//在(width-((width-s.length()-2)/2)-s.length()-2)个空格后拼接第四个参数即""。
//在宽度为19,高为9,字符串为“abcd1234”时最后的效果为
//在(19-8-2)/2 = 4(int会忽略小数点后的数并非四舍五入)个空格后拼接一个""(空字符串)(空字符串不是空格)又拼
//接字符串“abcd1234”又在(19-((19-8-2)/2)-8-2) = 5个空格后拼接一个""(空字符串)
//在这两串代码前后分别有一句System.out.print("|");
//即
//| abcd1234 |
//"%s%s%s"在String.format(ff,"",s,"")中的意思是把
//String.format()格式化方法中的第二、第三、第四个参数直接拼接在一起
//因为""为空字符串,所以显示不出来
//所以在宽度为6,高为9,字符串为“abcd1234”时最后的效果为:
//因为width<s.length()所以字符串长度被截短为width - 2(6 - 2 = 4),字符串为“abcd”。
//即
//|abcd|
String ff = width>s.length()+2?("%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"):"%s%s%s"; //填空
System.out.print(String.format(ff,"",s,""));
System.out.println("|");
for(int k=(height-1)/2+1; k<height-1; k++){
System.out.print("|");
for(int i=0;i<width-2;i++) System.out.print(" ");
System.out.println("|");
}
System.out.print("+");
for(int i=0;i<width-2;i++) System.out.print("-");
System.out.println("+");
}
}
最后修改的答案为:
width>s.length()+2?("%1$"+(width-s.length()-2)/2+"s%2$s%3$"+(width-((width-s.length()-2)/2)-s.length()-2)+"s"):"%s%s%s";
总结
一、考试时写上面参考的两篇文档的其中一个答案即可,当然写本文中的修改答案也可以。
二、平时可以以积累为主,多看看不同的答案。