首先看一下题
描述
按照指定规则对输入的字符串进行处理。
详细描述:
第一步:将输入的两个字符串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.第一步:将输入的两个字符串str1和str2进行前后合并。
4.如给定字符串“dec”和字符串“fab”,合并后生成的字符串为“decfab”
5.第二步:对合并后的字符串进行排序,要求为:
6.下标为奇数的字符和下标为偶数的字符分别从小到大排列。
7.这里的下标的意思是字符在字符串中的位置。
8.注意排序后在新串中仍需要保持原来的奇偶性。
9.例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符‘d’,‘c’,‘a’
和下标为奇数的字符‘e’,‘f’,‘b’进行排序
(生成‘a’,‘c’,‘d’和‘b’,‘e’,‘f’)
10.再分别放回原串中的偶数位和奇数位,
11.新字符串变为“abcedf”
12.第三步:对排序后的字符串中的‘0’~‘9’、‘A’~‘F’和‘a’~‘f’字符,需要进行转换操作
13.转换规则如下:对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序
14.然后再转换成对应的十六进制大写字符
(注:字符a~f的十六进制对应十进制的10~15,大写同理)。
15.如字符‘4’,其二进制为0100,则翻转后为0010,也就是2.转换后的字符为‘2’。
如字符‘7’,其二进制为0111,则翻转后为1110,对应的十进制是14,转换为十六进制的大写字母为‘E’。
如字符‘C’,代表的十进制是12,其二进制为1100,则翻转后为0011,也就是3.转换后的字符是‘3’。
根据这个转换规则,由第二步生成的字符串“abcedf”转换后会生成字符串“5D37BF”。
16.数据范围:输入的字符串长度满足n大于等于1小于等于100
17.输入描述:样例输入两个字符串,用空格隔开。
18.输出描述:输出转化后的结果。
二、解题思路
1.首先我们先定义两个字符串char str1[201];char str2[101];
2.然后我们将输入读取到字符串中
scanf("%s %s", str1, str2);
3.然后我们执行步骤1,为此我们需要函数strcat(str1,str2);
我们的strcat函数会将str2的内容复制到str1后面
4.完成字符串合并后我们执行步骤2
5.我们要分别对下标为偶数和奇数的字符进行排序(注意要按ascii码排序,所以大写字母在小写字母前面)
我们先对奇数字符排序
排序之前我们测量一下合并后的字符串长度int len = strlen(str1);
for(int i = 0; i < len; i = i + 2)
if(i >= len) break;
遍历奇数字符
for(int j = i + 2; j < len; j = j + 2)
if(j >= len) break;
每个奇数字符和后面的字符做对比,如果遇到比自己的ascii码小的字符,就交换位置(将ascii码小的放在前面)
if(str1[j] < str1[i]) {
char temp = str1[i];
str1[i] = str1[j];
str1[j] = temp;
}
然后我们对偶数字符排序
for(int i = 1; i < len; i = i + 2)
if(i >= len) break;
for(int j = i + 2; j < len; j = j + 2)
if(j >= len) break;
if(str1[j] < str1[i]) {
char temp = str1[i];
str1[i] = str1[j];
str1[j] = temp;
}
6.我们执行第三步,对于排序后的字符进行转换操作
将我们的每一个字符,当成十六进制,并计算出它的二进制表示,然后将二进制的表示倒序,然后再转换成相应的十六进制
因为二进制从0000到1111是十进制的0到15(1+2+4+8),十六进制的0到F
所以我们不用担心有无法转换的情况发生。
那么具体如何操作呢
for(int i = 0; i < len; i++)
首先我们需要计算我们字符的二进制表示
我们如果要想知道二进制表示我们需要先得到十进制表示
我们用一个int num;表示十进制
所以我们对字符做判断
if(c >= '0' && c <= '9')如果我们这个字符是‘0’-‘9’之间的字符(ascii码在‘0’至‘9’)
那么我们这个字符是个数字我们可以直接给num赋值
num = c - '0';
if(c >= 'a' && c <= 'f')如果我们这个字符是一个小写字母
num = c - 'a';
if(c >= 'A' && c <= 'F')如果是大写字母
num = c - 'A';
这样我们就得到了我们字符相对应的十进制数字
接下来我们转换成二进制(直接储存为翻转后的形式);
int binary[4];
for(int i = 0; i < 4; i++){
binary[i] = num % 2;
num /= 2;
}
然后我们将翻转后的二进制转换为十进制
int newnum = 0;
for(int i = 0; i < 4; i++){
newnum += pow(binary[i], 2)
}
然后我们得到我们转换后的字符
if(newnum <= 9){
c = newnum + '0';
} else {
c = newnum - 10 + 'A';
}
三、具体步骤
使用的语言是C,有一点要注意的是,如果是非十六进制能识别的字符,我们不做处理。
#include <stdio.h>
#include <string.h>
void stepthree(char *c) {
int num;
if(*c >= '0' && *c <= '9') {
num = *c - '0';
} else if (*c >= 'a' && *c <= 'f') {
num = *c - 'a' + 10;
} else if (*c >= 'A' && *c <= 'F') {
num = *c - 'A' + 10;
} else {
return;
}
// printf("转换后的十进制数是%d\n", num);
int binary[4];
for(int i = 0; i < 4; i++) {
binary[i] = num % 2;
num /= 2;
}
int newnum = 0;
for(int i = 0; i < 4; i++) {
newnum = newnum * 2 + binary[i];
}
if(newnum >= 0 && newnum <= 9) {
*c = newnum + '0';
} else if (newnum > 9 && newnum <= 15) {
*c = newnum - 10 + 'A';
}
}
int main() {
char str1[201], str2[101];
while (scanf("%s %s", str1, str2) != EOF) {
// 第一步
strcat(str1, str2);
// 第二步
int len = strlen(str1);
for(int i = 0; i < len; i = i + 2) {
if(i >= len) break;
for(int j = i + 2; j < len; j = j + 2) {
if(j >= len) break;
if(str1[j] < str1[i]) {
int temp = str1[j];
str1[j] = str1[i];
str1[i] = temp;
}
}
}
for(int i = 1; i < len; i = i + 2) {
if(i >= len) break;
for(int j = i + 2; j < len; j = j + 2) {
if(j >= len) break;
if(str1[j] < str1[i]) {
int temp = str1[j];
str1[j] = str1[i];
str1[i] = temp;
}
}
}
// 第三步
for(int i = 0; i < len; i++) {
stepthree(&str1[i]);
}
printf("%s\n", str1);
}
return 0;
}
标签:字符,排序,int,str1,len,华为,字符串,机试,HJ30
From: https://blog.csdn.net/bingw0114/article/details/143438867