前言
这道题去年参加蓝桥的时候我就做过了,但是因为c/c++对于字符串的支持不是很好(主要还是菜)一直没做出来,昨天下定决心把这道题给过了,这道题其实不是很难,但是对于细节的处理特别麻烦,为此,我写了好几个方法去实现它。
题目链接
分析
我们先来看下输入输出的样例,题目描述可以打开上面的那个链接查看:
1 2 3
| 输入1: 1 2 1 abcs-w1234-9s-4zz
|
1 2
| 输出1: abcsttuuvvw1234556677889s-4zz
|
这道题可以说是考细节方面的处理的,我到最后一直有两个点过不去,后来下载数据发现我没有考虑到数字0-9的情况,也就是checkLianXu这个函数。所以一定要理清思绪再来,不然会很懵逼的。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
| import java.util.Scanner;
public class P1098字符串的展开 { public static int P1, P2, P3; public static String data;
public static void main(String[] args) { Scanner sc = new Scanner(System.in); P1 = sc.nextInt(); P2 = sc.nextInt(); P3 = sc.nextInt(); data = sc.next();
for (int i = 0; i < data.length(); i++) { char c = data.charAt(i); if (c == '-') {
if (i - 1 < 0 || i + 1 >= data.length()) { System.out.print('-'); continue; }
char s = data.charAt(i - 1); char e = data.charAt(i + 1);
if (checkXiangLin(s, e)) { continue; }
if (!checkLianXu(s, e)) { System.out.print('-'); continue; } if (P3 == 1) { System.out.print(reverseStringForward(s, e, P2, P1)); continue; } else { System.out.print(reverseStringReverse(s, e, P2, P1)); continue; } } System.out.print(c); }
}
private static boolean checkXiangLin(char s, char e) { int startASCII = (int) s; int endASCII = (int) e;
return startASCII + 1 == endASCII; }
public static String reverseStringForward(char s, char e, int count, int type) { StringBuilder sb = new StringBuilder(); int startASCII = (int) s; int endASCII = (int) e;
for (int i = s + 1; i <= e - 1; i++) { for (int j = 1; j <= count; j++) { char c = (char) i; if (type == 1) { if (!isNum(c)) { if (!isCapital(c)) c = (char) (c + 32); } } else if (type == 2) { if (!isNum(c)) { if (isCapital(c)) c = (char) (c - 32); } } else if (type == 3) { c = '*'; } sb.append(c); } } return sb.toString(); }
private static boolean isNum(char c) { return (c >= 49 && c <= 57); }
public static String reverseStringReverse(char s, char e, int count, int type) { StringBuilder sb = new StringBuilder(); int startASCII = (int) s; int endASCII = (int) e;
for (int i = e - 1; i >= s + 1; i--) { for (int j = 1; j <= count; j++) { char c = (char) i; if (type == 1) { if (!isNum(c)) { if (isCapital(c)) c = (char) (c + 32); } } else if (type == 2) { if (!isNum(c)) { if (isCapital(c)) c = (char) (c - 32); } } else if (type == 3) { c = '*'; } sb.append(c); } } return sb.toString(); }
public static boolean isCapital(char c) { return !(c >= 49 && c <= 57); }
public static boolean checkLianXu(char s, char e) { int startASCII = (int) s; int endASCII = (int) e;
if ((endASCII <= startASCII || startASCII + 1 == endASCII)) { return false; }
return (startASCII >= 48 && endASCII <= 57) || (startASCII >= 65 && endASCII <= 65 + 32) || (startASCII >= 97 && endASCII <= 97 + 35); } }
|
代码应该不难理解,我把主要的部分划分成了几个函数,分别是:
- checkLianXu 检查是否符合连续性规则(那两个点就是栽倒数字0-9中的0了)
- isCapital 检查当前字符是大写的还是小写的
- reverseStringReverse 反向生成字符串,参数具体是什么方法头已经写了
- checkXiangLin 主要检查两个字符是否是相邻的,也就是0-1这种情况
- reverseStringForward 正向生成字符串
对了,main方法里面的for循环题内的i - 1 < 0 || i + i >= data.length()
主要是检查数据开头和结尾是否包含-
这个字符。
结语
明天见。