华为机试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.第一步:将输入的两个字符串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;
}
上一篇:FFmpeg - 音视频文件编码


下一篇:.NET中通过C#实现Excel与DataTable的数据互转-将数据从Excel表格导入DataTable