注意:代码和解题思路在后面
HJ30 字符串合并处理
描述 按照指定规则对输入的字符串进行处理。详细描述:
第一步:将输入的两个字符串str1和str2进行前后合并。如给定字符串 “dec” 和字符串 “fab” , 合并后生成的字符串为 “decfab”
第二步:对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标的意思是字符在字符串中的位置。注意排序后在新串中仍需要保持原来的奇偶性。例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符’d’、‘c’、‘a’和下标为奇数的字符’e’、‘f’、'b’进行排序(生成 ‘a’、‘c’、‘d’ 和 ‘b’ 、‘e’ 、‘f’),再依次分别放回原串中的偶数位和奇数位,新字符串变为“abcedf”
第三步:对排序后的字符串中的’0’‘9’、‘A’‘F’和’a’~'f’字符,需要进行转换操作。
转换规则如下:
对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序,然后再转换成对应的十六进制大写字符(注:字符 a~f 的十六进制对应十进制的10~15,大写同理)。
如字符 ‘4’,其二进制为 0100 ,则翻转后为 0010 ,也就是 2 。转换后的字符为 ‘2’。
如字符 ‘7’,其二进制为 0111 ,则翻转后为 1110 ,对应的十进制是14,转换为十六进制的大写字母为 ‘E’。
如字符 ‘C’,代表的十进制是 12 ,其二进制为 1100 ,则翻转后为 0011,也就是3。转换后的字符是 ‘3’。
根据这个转换规则,由第二步生成的字符串 “abcedf” 转换后会生成字符串 “5D37BF”。
数据范围:输入的字符串长度满足 1≤n≤100
输入描述:
样例输入两个字符串,用空格隔开。
输出描述:
输出转化后的结果。
示例1
输入:
dec fab
输出:
5D37BF
示例2
输入:
ab CD
输出:
3B5D
说明:
合并后为abCD,按奇数位和偶数位排序后是CDab(请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D
示例3
输入:
123 15
输出:
88C4A
参考思路和代码及详细注释
参考思路;
1、先合并字符串
2、将合并后的字符串进行排序并转换成字符数组
3、按照规则计算得到最终结果:
规则1:如果字符是字母,则先将字母转换成十进制,再将十进制转换成二进制,再将二进制翻转,再将翻转后的二进制张成十进制,如果转换成十进制后的
数据在[10,15]区间,则将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
规则2:如果字符是数字,则先将数字转换成二进制,再降二进制翻转,再将翻转后的二进制转换成十进制,如果转换成十进制后的数据在
[10,15]区间,则将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
规则3:这是个坑,一定要注意。如果不在[a,f]或者[A,F]区间的则直接写入结果字符串中。我在写的时候没有注意这个,所以提交结果测试 半天,结果集不对
测试数据:Eqr v9oEb12U2ur4xu7rd931G1f50qDo
没有加规则3时答案:8084842CAE9B97D7BF
加了规则3后答案:8084842CAE9B9G7D7BUFooqqrrrvuxu
参考代码和详细注释:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;
/**
* @Author lqs
* @Date 2022年05月19日 10:12:04
* @Version 1.0.0
* @ClassName ms
* @Describe
*/
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String[] split = input.nextLine().split(" ");
//合并字符串
String mergeStr = mergeString(split);
//测试用
// System.out.println(mergeStr);
//排序字符串
char[] parityIndexSort = parityIndexSort(mergeStr);
//测试用
// for (char c : parityIndexSort) {
// System.out.print(c + " ");
// }
//按照规则转换字符串,并输出转换后的结果
System.out.println(ruleConversion(parityIndexSort));
}
/**
* 将多个字符串按照顺序合并为一个字符串
*
* @param strArray 传入需要合并的字符串数组
* @return 返回按照顺序合并好后的数组
*/
private static String mergeString(String[] strArray) {
StringBuilder mergeStr = new StringBuilder();
for (String s : strArray) {
mergeStr.append(s);
}
return mergeStr.toString();
}
/**
* 对需要排序的字符串,按照奇数和偶数下标对应的值进行排序,并返回按照奇数和偶数下标排序好后的字符数组
*
* @param sortStr 需要按照奇数和偶数下标对应值进行排序的字符串
* @return 返回排序好后的字符串
*/
private static char[] parityIndexSort(String sortStr) {
char[] sortArray = sortStr.toCharArray();
ArrayList<Character> oddNumber = new ArrayList<>();//奇数下标值数组
ArrayList<Character> even = new ArrayList<>();//偶数下标值数组
//先按照奇、偶进行分组排序
oddNumber.add(sortArray[1]);
even.add(sortArray[0]);
for (int i = 2; i < sortArray.length; i++) {
if (i % 2 == 0) {
even.add(sortArray[i]);
} else {
oddNumber.add(sortArray[i]);
}
}
//对奇数下标对应值进行排序
oddNumber.sort(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o1 - o2;
}
});
//对偶数下标对应值进行排序
even.sort(new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o1 - o2;
}
});
//将排序好的奇数和偶数下标索引对应的值按奇数和偶数下标对应对应的值合并到一起
sortArray[0] = even.get(0);
sortArray[1] = oddNumber.get(0);
int i = 1;
int j = 1;
for (int k = 2; k < sortArray.length; k++) {
if (k % 2 == 0) {
sortArray[k] = even.get(i++);
} else {
sortArray[k] = oddNumber.get(j++);
}
}
return sortArray;
}
/**
* 将字符数组按照规则进行转换
* 规则1:如果字符是字母,则先将字母转换成十进制,再将十进制转换成二进制,再将二进制翻转,再将翻转后的二进制张成十进制,如果转换成十进制后的
* 数据在[10,15]区间,则将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
* 规则2:如果字符是数字,则先将数字转换成二进制,再降二进制翻转,再将翻转后的二进制转换成十进制,如果转换成十进制后的数据在[10,15]区间,则
* 将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
* 规则3:这是个坑,一定要注意。如果不在[a,f]或者[A,F]区间的则直接写入结果字符串中。我在写的时候没有注意这个,所以提交结果测试半天,结果集不对
* 测试数据:Eqr v9oEb12U2ur4xu7rd931G1f50qDo
* 没有加规则3时答案:8084842CAE9B97D7BF
* 加了规则3后答案:8084842CAE9B9G7D7BUFooqqrrrvuxu
*
* @param sortCharArray 需要按规则转换的字符数组
* @return 返回按规则转换好后的数组
*/
private static String ruleConversion(char[] sortCharArray) {
StringBuilder ruledConversionStr = new StringBuilder();
for (char c : sortCharArray) {
if (Character.isLetter(c)) {//处理a~f或者A~F
char toUpperCase = Character.toUpperCase(c);
if (toUpperCase >= 'A' && toUpperCase <= 'F') {
//将对应的字母转换为十进制
int letterToDecimal = getLetterToDecimal(toUpperCase);
//将转换好后的十进制转换成二进制翻转后再转换成十进制
int flipBinaryToDecimal = getDecimalToBinaryAndFlipBinaryToDecimal(letterToDecimal);
//如果转换后的十进制是大于等于10,小于等于15,则转换成16进制对应的字母
if (flipBinaryToDecimal >= 10 && flipBinaryToDecimal <= 15) {
//将数字转换成对应16进制的大写字母,并写入结果字符串中
ruledConversionStr.append(getDecimalToLetter(flipBinaryToDecimal));
} else {//小于10大于等于0的十进制数直接写入结果字符串中
ruledConversionStr.append(flipBinaryToDecimal);
}
} else {//注意!注意!注意!如果不在[a,f]或者[A,F]区间的则直接写入结果字符串中
ruledConversionStr.append(c);
}
} else {//对0~9进行处理
//将数字转化为二进制,再对二进制进行翻转,在把翻转后的二进制转换成十进制
int decimalToBinaryAndFlipBinaryToDecimal = getDecimalToBinaryAndFlipBinaryToDecimal(Integer.parseInt(String.valueOf(c)));
if (decimalToBinaryAndFlipBinaryToDecimal >= 10 && decimalToBinaryAndFlipBinaryToDecimal <= 15) {
ruledConversionStr.append(getDecimalToLetter(decimalToBinaryAndFlipBinaryToDecimal));
} else {
ruledConversionStr.append(decimalToBinaryAndFlipBinaryToDecimal);
}
}
}
return ruledConversionStr.toString();
}
/**
* 将字母转换成对应的十进制
*
* @param c 需要转换的为十进制的字母
* @return 返回字母转换好后的十进制
*/
private static int getLetterToDecimal(char c) {
;
switch (c) {
case 'A':
return 10;
case 'B':
return 11;
case 'C':
return 12;
case 'D':
return 13;
case 'E':
return 14;
case 'F':
return 15;
}
return 0;
}
/**
* 将十进制的数组转换成二进制后,再对二进制翻转,再将翻转后的二进制转换成十进制
*
* @param number 传入需要转换的十进制
* @return 返回转换好后的十进制数字
*/
private static int getDecimalToBinaryAndFlipBinaryToDecimal(int number) {
ArrayList<Integer> flipBinary = new ArrayList<>();
int tmp = number;
for (int i = 1; i <= tmp; i++) {
if (number % 2 == 0) {
flipBinary.add(0);
number /= 2;
} else {
flipBinary.add(1);
number /= 2;
}
if (number == 1) {
flipBinary.add(1);
break;
}
}
//如果计算出来的二进制没有四位,则在其后面补0
while (flipBinary.size() < 4) {//while循环是先做后判断
flipBinary.add(0);
}
return getBinaryToDecimal(flipBinary);
}
/**
* 将二进制转换成十进制
*
* @param binary 需要转换的二进制列表
* @return 返回转换好后的十进制数
*/
private static int getBinaryToDecimal(ArrayList<Integer> binary) {
int n = binary.size();
int decimalNumber = 0;
for (int i = 0; i < n; i++) {
decimalNumber += Math.pow(2, n - i - 1) * binary.get(i);//pow:求2的n-i-1次方的值,100,1*pow(2,3-0-1)+1*pow(2,3-1-1)+1*pow(2,3-2-1)
}
return decimalNumber;
}
/**
* 将数字转换成对应的16进制的大写字母
*
* @param number 需要转换的数字
* @return 返回转换好后的字母
*/
private static char getDecimalToLetter(int number) {
switch (number) {
case 10:
return 'A';
case 11:
return 'B';
case 12:
return 'C';
case 13:
return 'D';
case 14:
return 'E';
case 15:
return 'F';
}
return 'X';
}
}