题目要求:
输入一个不大于 13 的正整数 n 和 一个大写字母 ch ; 输入以字母 ch为中心,边长为n 的 X形式图案 ,其中 从上往下看,在 X图案 的4条边 字母都是依次递增;大写字母 中 'A -- Z' 按照顺序 构成环形结构, 即 A-Z-A .....循环注意: 若n>13 或者 n <= 0 或 输入的字母不是大写字母, 输出Input Data Error 结束程序;
示例:输入 n=4 ,ch = ‘X’;
得到:
简单思路, 分析示例数据, X图案实际可看做上下对称的两部分,
中间行为 ch 字母所在行, 从中间行向上逐渐递减;从中间行向下逐渐递增;
大写字母循环结束则回到起始或结束字母A或Z;
逐行处理即可;
代码示例
package com.lzq.demo2023;
/**
* @BelongsProject: xiaozhire0goods
* @BelongsPackage: com.lzq.demo2023
* @Author: 小智RE0 --- 学习记录
* @Date: 2023/1/24 21:27
* @Description: TODO
*/
public class CompareNumAndChar {
/**
* 输入一个不大于 13 的正整数 n 和 一个大写字母 ch ; 输入以字母 ch为中心,边长为n 的 X形式图案
* ,其中 从上往下看,在 X图案 的4条边 字母都是依次递增;
*
* 大写字母 中 'A -- Z' 按照顺序 构成环形结构, 即 A-Z-A ... ,
* 注意: 若n>13 或者 n <= 0 或 输入的字母不是大写字母, 输出Input Data Error 结束程序;
*
* 大写字母 A-65 Z -90
示例
---------------------------------------
*
* 7 A 行数 左侧点数 总点数 字母数
*
* U...........U 0 0 11 2
* .V.........V. 1 1 11 2
* ..W.......W.. 2 2 11 2
* ...X.....X... 3 3 11 2
* ....Y...Y.... 4 4 11 2
* .....Z.Z..... 5 5 11 2
* ......A...... 6 6 11 1
* .....B.B..... 7 5 11 2
* ....C...C.... 8 4 11 2
* ...D.....D... 9 3 11 2
* ..E.......E.. 10 2 11 2
* .F.........F. 11 1 11 2
* G...........G 12 0 11 2
*/
/**
* 参数 4 X
*
* U.....U
* .V...V.
* ..W.W..
* ...X...
* ..Y.Y..
* .Z...Z.
* A.....A
*
*/
private static String printPhoto(int n, char ch) {
//入参校验;\
if (n > 13 || n <= 0 || ch < 65 || ch > 90) {
System.out.println("Input Data Error");
}
StringBuilder photo = new StringBuilder();
//按题意得到边长为 totalrRow;
int totalrRow = (n -1) * 2 + 1;
for (int i = 0; i < totalrRow; i++) {
//处理这一行的方法;要素 点. 字母,以及行位数;
photo = dealDataRow(i, totalrRow, ch, photo);
//换行;
photo.append("\n");
}
return photo.toString();
}
/**
* 处理单独行的实际显示图案;
*
* @param rows 当前的行数
* @param n 总行数
* @param centerChar 中间的字母;
* @return
*/
private static StringBuilder dealDataRow(int rows,
int n,
char centerChar,
StringBuilder photo) {
//点图案;
String point = ".";
//中间行:
int middleRow = n / 2;
//中间行和当前行的间隔数;
int intervalNum = 0;
if (rows == middleRow) {
//中间行处理;
//左侧点;
for (int i = 0; i < rows; i++) {
photo.append(point);
}
//中心字母
photo.append(centerChar);
//右侧点;
for (int i = 0; i < rows; i++) {
photo.append(point);
}
} else if (rows < middleRow) {
//中间行之前的行;
intervalNum = middleRow - rows;
dealTopOrDownPhoto(true, rows, n, centerChar, photo, intervalNum);
} else {
//中间行之后的行;
//改变当前行数; 即对称的这个;
//rows - middleRow: 当前行与中间行的隔位 ;
intervalNum = rows - middleRow;
rows = middleRow - intervalNum;
dealTopOrDownPhoto(false, rows, n, centerChar, photo, intervalNum);
}
return photo;
}
/**
* 处理上下部分的图案
*
* @param isTop 是否为上半部分; 上半: 递减字母 下半:递增字母;
* @param photo
* @param rows
* @param n
* @param centerChar
* @return
*/
private static StringBuilder dealTopOrDownPhoto(boolean isTop,
int rows,
int n,
char centerChar,
StringBuilder photo,
int intervalNum) {
//点图案;
String point = ".";
//当前行使用的大写字母;
char majuscule;
//左侧点
for (int i = 0; i < rows; i++) {
photo.append(point);
}
//左侧字母;
majuscule = dealCh(centerChar, isTop, intervalNum);
photo.append(majuscule);
//中间点: 当前行的列数 - 2*字母数 - 2*左侧点数
int middlePointNum = n - 2 - 2 * rows;
for (int i = 0; i < middlePointNum; i++) {
photo.append(point);
}
//右侧字母;
photo.append(majuscule);
//右侧点
for (int i = 0; i < rows; i++) {
photo.append(point);
}
return photo;
}
/**
* 处理输出显示的字母 A-Z -A-Z...环形; A-65 Z-
*
* @param centerChar
* @param isTop
* @param intervalNum 间隔数, 比如 A-C 间隔数为2;
* @return
*/
private static char dealCh(char centerChar, boolean isTop, int intervalNum) {
//startCh :起始字符;
for (int i = 0; i < intervalNum; i++) {
if (isTop) {
//上半行 递减;
centerChar--;
} else {
//下半行 递增;
centerChar++;
}
centerChar = dealCh(centerChar);
}
return centerChar;
}
/**
* 处理输出显示的字母 A-Z -A-Z...环形绕过;
*
* @param ch
* @return
*/
private static char dealCh(char ch) {
//若字母大于Z ; 则显示为 A;
if (ch > 90) {
ch = 65;
} else if (ch < 65) {
//若字母小于A,则显示为 Z;
ch = 90;
}
return ch;
}
//主方法;
public static void main(String[] args) {
//运行;
System.out.println(printPhoto(4, 'X'));
}
}
运行效果:
输入n = 4,ch = X;
输入 n = 13,ch =B;