题意整理。

  • 输入一行字符串,包含两个字符串以空格隔开,对这两个字符串按指定规则进行处理。
  • 规则如下:第一步,合并这两个字符串。第二步,对合并后的字符串进行排序,要求分别对奇数位置和偶数位置的数进行排序, 排序后的数仍然放回原来的奇数位或偶数位。第三步,对排序后的字符串中的'0'-'9'、'A'-'F'和'a'-'f'字符,需要进行转换操作。首先转换为对应的四位二进制数,然后反转,在转换为对应的十六进制数。

方法一(模拟)

1.解题思路

  • 首先新建两个list容器,用于存储奇数位置的数,和偶数位置的数。然后将两个字符串合并,遍历整个字符串,将对应位置的数放到list容器odds和events。
  • 分别对odds和events进行排序,然后重新放回到对应的奇数位和偶数位。
  • 将处理之后的字符串按照第三步的转换规则,对特定字符,先转为二进制数,再反转,再转为十六进制数。

图解展示: alt

2.代码实现

import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Main{
    
    public static void main(String[] args){
        //标准输入
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            //待处理的字符串s1
            String s1=sc.next();
            //待处理的字符串s2
            String s2=sc.next();
            String s=handle(s1,s2);
            System.out.println(transform(s));
        }
    }
       
    //第一步和第二步
    private static String handle(String s1,String s2){
        //存储奇数位置的数
        List<Character> odds=new ArrayList<>();
        //存储偶数位置的数
        List<Character> events=new ArrayList<>();
        String s=s1+s2;
        int n=s.length();
        for(int i=0;i<n;i++){
            char c=s.charAt(i);
            if(i%2==0){
                odds.add(c);
            }
            else{
                events.add(c);
            }
        }
        //分别对奇数位置和偶数位置的数进行排序
        Collections.sort(odds);
        Collections.sort(events);
        //记录处理之后的结果
        StringBuilder res=new StringBuilder();
        int idx1=0;
        int idx2=0;
        for(int i=0;i<n;i++){
            //将奇数位的数存到原来对应的奇数位置
            if(i%2==0){
                res.append(odds.get(idx1++));
            }
            //将偶数位的数存到原来对应的偶数位置
            else{
                res.append(events.get(idx2++));
            }
        }
        return res.toString();
    }
    
    //第三步
    private static String transform(String s){
        int n=s.length();
        StringBuilder res=new StringBuilder();
        for(int i=0;i<n;i++){
            char c=s.charAt(i);
            //如果是大写'A'-'F',直接变为对应的小写
            if(c>='A'&&c<='F'){
                c=(char)(c+32);
            }
            //如果是'0'-'9'
            if(c>='0'&&c<='9'){
                int num=c-'0';
                //记录二进制反转后的值
                int t=0;
                for(int j=0;j<4;j++){
                    t=t*2+num%2;
                    num/=2;
                }
                if(t>=0&&t<=9){
                    res.append(t);
                }
                //如果大于等于10,转换为对应16进制
                else{
                    res.append((char)(t-10+'A'));
                }
            }
            //如果是'a'-'f'
            else if(c>='a'&&c<='f'){
                int num=c-'a'+10;
                //记录二进制反转后的值
                int t=0;
                for(int j=0;j<4;j++){
                    t=t*2+num%2;
                    num/=2;
                }
                if(t>=0&&t<=9){
                    res.append(t);
                }
                //如果大于等于10,转换为对应16进制
                else{
                    res.append((char)(t-10+'A'));
                }
            }
            else{
                res.append(c);
            }
        }
        return res.toString();
    }
}

3.复杂度分析

  • 时间复杂度:假设n为字符串s1和字符串s2长度之和,第一步和第三步均需要遍历整个字符串,时间复杂度为O(n)O(n),第二部需要分别对奇数位置和偶数位置的数进行排序,时间复杂度为O(nlog2n)O(n*log_2n)级别,所以时间复杂度为O(nlog2n)O(n*log_2n)
  • 空间复杂度:需要额外大小为n的list容器来存储奇数位置的数和偶数位置的数,所以空间复杂度为O(n)O(n)

方法二(利用io流)

1.解题思路

思路和方法一基本一致,不同的是通过io流操作来处理输入的数据。

2.代码实现

import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

public class Main{
    
    public static void main(String[] args) throws Exception{
        //标准输入
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        //输入的一行字符串s以及待处理的字符串s1、s2
        String s,s1,s2;
        while((s=br.readLine())!=null){
            String[] arr=s.split(" ");
            s1=arr[0];
            s2=arr[1];
            System.out.println(transform(handle(s1,s2)));
        }
    }
       
    //第一步和第二步
    private static String handle(String s1,String s2){
        //存储奇数位置的数
        List<Character> odds=new ArrayList<>();
        //存储偶数位置的数
        List<Character> events=new ArrayList<>();
        String s=s1+s2;
        int n=s.length();
        for(int i=0;i<n;i++){
            char c=s.charAt(i);
            if(i%2==0){
                odds.add(c);
            }
            else{
                events.add(c);
            }
        }
        //分别对奇数位置和偶数位置的数进行排序
        Collections.sort(odds);
        Collections.sort(events);
        //记录处理之后的结果
        StringBuilder res=new StringBuilder();
        int idx1=0;
        int idx2=0;
        for(int i=0;i<n;i++){
            //将奇数位的数存到原来对应的奇数位置
            if(i%2==0){
                res.append(odds.get(idx1++));
            }
            //将偶数位的数存到原来对应的偶数位置
            else{
                res.append(events.get(idx2++));
            }
        }
        return res.toString();
    }
    
    //第三步
    private static String transform(String s){
        int n=s.length();
        StringBuilder res=new StringBuilder();
        for(int i=0;i<n;i++){
            char c=s.charAt(i);
            //如果是大写'A'-'F',直接变为对应的小写
            if(c>='A'&&c<='F'){
                c=(char)(c+32);
            }
            //如果是'0'-'9'
            if(c>='0'&&c<='9'){
                int num=c-'0';
                //记录二进制反转后的值
                int t=0;
                for(int j=0;j<4;j++){
                    t=t*2+num%2;
                    num/=2;
                }
                if(t>=0&&t<=9){
                    res.append(t);
                }
                //如果大于等于10,转换为对应16进制
                else{
                    res.append((char)(t-10+'A'));
                }
            }
            //如果是'a'-'f'
            else if(c>='a'&&c<='f'){
                int num=c-'a'+10;
                //记录二进制反转后的值
                int t=0;
                for(int j=0;j<4;j++){
                    t=t*2+num%2;
                    num/=2;
                }
                if(t>=0&&t<=9){
                    res.append(t);
                }
                //如果大于等于10,转换为对应16进制
                else{
                    res.append((char)(t-10+'A'));
                }
            }
            else{
                res.append(c);
            }
        }
        return res.toString();
    }
}

3.复杂度分析

  • 时间复杂度:假设n为字符串s1和字符串s2长度之和,第一步和第三步均需要遍历整个字符串,时间复杂度为O(n)O(n),第二部需要分别对奇数位置和偶数位置的数进行排序,时间复杂度为O(nlog2n)O(n*log_2n)级别,所以时间复杂度为O(nlog2n)O(n*log_2n)
  • 空间复杂度:需要额外大小为n的list容器来存储奇数位置的数和偶数位置的数,所以空间复杂度为O(n)O(n)