解题思路:
- 考点:
- 进制转换 (纯代码转,非暴力)
- a-f和A-F 需要转换, 二进制翻转之后 最终转的16进制 需对应到大写字母。
- 数组奇偶排序之后再合并 细节处理。
- 字符串的翻转 : 使用双指针实现
- 如某个小考点 有更优解, 请指出哈。
import java.util.Scanner;
import java.util.Arrays;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) { // 注意 while 处理多个 case
// 1. 字符排序
// 2. 将小写字符 转 二进制,将二进制倒序后 转为16进制大写字符。 (涉及到二进制字符串的翻转)
String param = in.nextLine();
// 合并字符串
param = param.replace(" ", "");
// 奇偶数排序
char[] chars = param.toCharArray();
int n = chars.length % 2 == 1 ? chars.length / 2 + 1 : chars.length / 2;
char[] qi = new char[chars.length / 2];
char[] ou = new char[n];
for (int i = 0; i < chars.length; i++) {
if (i % 2 == 0) {
ou[i / 2] = chars[i];
} else qi[i / 2] = chars[i];
}
// 奇偶排序
Arrays.sort(qi);
Arrays.sort(ou);
// 合并字符串 重新赋值到数组
int j = 0;
for (int i = 0; i < ou.length; i++) {
chars[j] = ou[i];
// 奇数长度的chars qi长度比ou小1
if (i == ou.length - 1) {
if (chars.length % 2 == 0) chars[j + 1] = qi[i];
} else {
chars[j + 1] = qi[i];
}
j += 2;
}
String noSwitch = "abcdefABCDEF";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (Character.isDigit(chars[i])) {
// 数字 转二进制,翻转,转十进制,转16进制
sb.append(getSixteenNum(Character.getNumericValue(chars[i])));
} else if (!noSwitch.contains(String.valueOf(chars[i]))) sb.append(chars[i]);
else {
// 字符,先转为十进制,后续相同
int decimalHex = Integer.parseInt(String.valueOf(chars[i]), 16);
sb.append(getSixteenNum(decimalHex));
}
}
System.out.println(sb.toString());
}
}
// 转二进制,翻转,转十进制,转16进制
public static String getSixteenNum(int x) {
// 十进制转二进制
String y = Integer.toBinaryString(x);
//二进制 如果小于四位,补零
while (y.length() < 4) {
y = "0" + y;
}
// 翻转
String res = reverseString(y.toCharArray());
// 转十进制
int z = Integer.parseInt(res, 2);
// 转16进制
String result = Integer.toString(z, 16);
if (z >= 10 && z <= 16) {
result = String.valueOf(Character.toUpperCase(result.charAt(0)));
}
return result;
}
// 双指针 翻转字符串
public static String reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
StringBuilder sb = new StringBuilder();
for (char c : s) {
sb.append(c);
}
return sb.toString();
}
}