校招算法笔面试 | 华为机试-字符串合并处理

题目## 题目

题目链接

解题思路

  1. 第一步:字符串合并
    • 将两个输入字符串直接拼接
  2. 第二步:字符排序
    • 将字符串中的字符按奇偶位置分别排序
    • 奇数位置和偶数位置的字符分别从小到大排序
    • 排序后放回原位置
  3. 第三步:进制转换
    • 对于数字和字母进行二进制转换和翻转
    • 将翻转后的二进制转换为对应的数字或大写字母

代码

def merge_strings(str1, str2):
    """第一步:合并字符串"""
    return str1 + str2

def sort_by_position(s):
    """第二步:按奇偶位置排序"""
    # 分离奇数位和偶数位字符
    odd_chars = sorted([s[i] for i in range(len(s)) if i % 2 == 0])
    even_chars = sorted([s[i] for i in range(len(s)) if i % 2 == 1])
    
    # 重新组合字符串
    result = []
    odd_idx = 0
    even_idx = 0
    for i in range(len(s)):
        if i % 2 == 0:
            result.append(odd_chars[odd_idx])
            odd_idx += 1
        else:
            result.append(even_chars[even_idx])
            even_idx += 1
    return ''.join(result)

def convert_char(c):
    """转换字符
    1. 数字:直接转二进制
    2. 字母:先转为对应的十六进制值(a-f:10-15, A-F:10-15),再转二进制
    3. 翻转二进制,转回十六进制
    """
    if c > 'f' and c <= 'z' or c > 'F' and c <= 'Z':
        return c;
    if c.isdigit():
        binary = format(int(c), '04b')
    else:
        # 字母转为对应的十六进制值(0-15)
        val = int(c, 16) if c.lower() <= 'f' else ord(c.lower()) - ord('a')
        binary = format(val, '04b')
    
    # 翻转二进制并转为十六进制
    reversed_val = int(binary[::-1], 2)
    return format(reversed_val, 'X')

def process_string(str1, str2):
    # 第一步:合并字符串
    merged = str1 + str2
    
    # 第二步:奇偶位置分别排序
    odd_pos = sorted(merged[::2])
    even_pos = sorted(merged[1::2])
    
    # 重新组合
    result = ''
    i, j = 0, 0
    for k in range(len(merged)):
        if k % 2 == 0:
            result += odd_pos[i]
            i += 1
        else:
            result += even_pos[j]
            j += 1
    
    # 第三步:进制转换
    return ''.join(convert_char(c) for c in result)

while True:
    try:
        str1, str2 = input().split()
        print(process_string(str1, str2))
    except EOFError:
        break
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;

string mergeStrings(const string& str1, const string& str2) {
    return str1 + str2;
}

string sortByPosition(const string& s) {
    vector<char> odd_chars, even_chars;
    for (int i = 0; i < s.length(); i++) {
        if (i % 2 == 0) odd_chars.push_back(s[i]);
        else even_chars.push_back(s[i]);
    }
    
    sort(odd_chars.begin(), odd_chars.end());
    sort(even_chars.begin(), even_chars.end());
    
    string result;
    int odd_idx = 0, even_idx = 0;
    for (int i = 0; i < s.length(); i++) {
        if (i % 2 == 0) result += odd_chars[odd_idx++];
        else result += even_chars[even_idx++];
    }
    return result;
}

char convertChar(char c) {
    if (c > 'f' && c <= 'z' || c > 'F' && c <= 'Z') {
        return c;
    }
    int val;
    if (isdigit(c)) {
        val = c - '0';
    } else {
        // 将字母转换为对应的十六进制值
        if (tolower(c) <= 'f') {
            string hex_str(1, c);
            val = stoi(hex_str, nullptr, 16);
        } else {
            val = tolower(c) - 'a';
        }
    }
    
    // 转为4位二进制并翻转
    string binary = bitset<4>(val).to_string();
    reverse(binary.begin(), binary.end());
    
    // 转回十六进制
    int reversed_val = bitset<4>(binary).to_ulong();
    if (reversed_val < 10) {
        return '0' + reversed_val;
    } else {
        return 'A' + (reversed_val - 10);
    }
}

string processString(const string& str1, const string& str2) {
    string merged = mergeStrings(str1, str2);
    string sorted = sortByPosition(merged);
    string result;
    for (char c : sorted) {
        result += convertChar(c);
    }
    return result;
}

int main() {
    string str1, str2;
    while (cin >> str1 >> str2) {
        cout << processString(str1, str2) << endl;
    }
    return 0;
}
import java.util.*;

public class Main {
    private static String mergeStrings(String str1, String str2) {
        return str1 + str2;
    }
    
    private static String sortByPosition(String s) {
        List<Character> oddChars = new ArrayList<>();
        List<Character> evenChars = new ArrayList<>();
        
        for (int i = 0; i < s.length(); i++) {
            if (i % 2 == 0) oddChars.add(s.charAt(i));
            else evenChars.add(s.charAt(i));
        }
        
        Collections.sort(oddChars);
        Collections.sort(evenChars);
        
        StringBuilder result = new StringBuilder();
        int oddIdx = 0, evenIdx = 0;
        for (int i = 0; i < s.length(); i++) {
            if (i % 2 == 0) result.append(oddChars.get(oddIdx++));
            else result.append(evenChars.get(evenIdx++));
        }
        return result.toString();
    }
    
    private static char convertChar(char c) {
        if (c > 'f' && c <= 'z' || c > 'F' && c <= 'Z') {
            return c;
        }
        int val;
        if (Character.isDigit(c)) {
            val = c - '0';
        } else {
            // 将字母转换为对应的十六进制值
            if (Character.toLowerCase(c) <= 'f') {
                val = Integer.parseInt(String.valueOf(c), 16);
            } else {
                val = Character.toLowerCase(c) - 'a';
            }
        }
        
        // 转为4位二进制并翻转
        String binary = String.format("%4s", Integer.toBinaryString(val)).replace(' ', '0');
        String reversed = new StringBuilder(binary).reverse().toString();
        
        // 转回十六进制
        int reversedVal = Integer.parseInt(reversed, 2);
        return reversedVal < 10 ? (char)('0' + reversedVal) : (char)('A' + (reversedVal - 10));
    }
    
    private static String processString(String str1, String str2) {
        String merged = mergeStrings(str1, str2);
        String sorted = sortByPosition(merged);
        StringBuilder result = new StringBuilder();
        for (char c : sorted.toCharArray()) {
            result.append(convertChar(c));
        }
        return result.toString();
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str1 = sc.next();
            String str2 = sc.next();
            System.out.println(processString(str1, str2));
        }
    }
}

算法及复杂度

  • 算法:字符串处理 + 排序 + 进制转换
  • 时间复杂度: O ( n log ⁡ n ) \mathcal{O}(n \log n) O(nlogn),其中n为合并后字符串的长度,主要来自排序操作
  • 空间复杂度: O ( n ) \mathcal{O}(n) O(n),需要额外空间存储排序和转换过程中的字符

题目链接

解题思路

  1. 读取输入的字符串
  2. 反转字符串的方法:
    • 方法1:使用语言内置的字符串反转函数
    • 方法2:手动实现字符串反转
    • 方法3:使用栈结构
  3. 输出反转后的结果
  4. 注意:
    • 字符串长度限制在1000以内
    • 只包含小写字母

代码

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string str;
    getline(cin, str);
    
    // 方法1:使用algorithm的reverse
    reverse(str.begin(), str.end());
    cout << str << endl;
    
    /* 方法2:手动反转
    string result;
    for(int i = str.length() - 1; i >= 0; i--) {
        result += str[i];
    }
    cout << result << endl;
    */
    
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        
        // 方法1:使用StringBuilder
        StringBuilder sb = new StringBuilder(str);
        System.out.println(sb.reverse().toString());
        
        /* 方法2:手动反转
        char[] chars = str.toCharArray();
        for(int i = 0, j = chars.length - 1; i < j; i++, j--) {
            char temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }
        System.out.println(new String(chars));
        */
    }
}
# 方法1:使用切片
s = input()
print(s[::-1])

'''
# 方法2:手动反转
s = input()
print(''.join(reversed(s)))

# 方法3:转换为列表反转
s = list(input())
s.reverse()
print(''.join(s))
'''

算法及复杂度

  • 算法:字符串反转
  • 时间复杂度: O ( n ) \mathcal{O}(n) O(n) - 其中n为字符串长度
  • 空间复杂度: O ( n ) \mathcal{O}(n) O(n) - 需要存储反转后的字符串
字符串重新排列是一道比较基础的编程问题,主要考察对字符串的基本操作以及算法思维的理解。实现的思路可以分为以下几个步骤: 1. 统计字符串中每个字符出现的次数,可以用一个数组来记录。如果字符串中有多个相同的字符,数组中对应的元素值需要加上相应的次数。 2. 根据每个字符出现的次数,生成一个新的字符串。比如说原字符串为"hello",那么新字符串的可能是"eolh"。这里需要注意的是,新字符串中相同的字符的顺序需要和原字符串中相同。 3. 需要考虑特殊情况,即原字符串中有空格或者特殊字符等,需要排除这些字符。 最后,我们来看一下具体的代码实现: ```js function rearrangeString(str) { // 统计每个字符出现的次数 const count = {}; for (let i = 0; i < str.length; i++) { const char = str[i]; if (/\w/.test(char)) { if (!count[char]) { count[char] = 1; } else { count[char]++; } } } // 生成新的字符串 let newStr = ''; Object.keys(count).sort((a, b) => count[b] - count[a]).forEach((char) => { newStr += char.repeat(count[char]); }); return newStr; } ``` 代码中,我们首先定义一个count对象用来存储每个字符出现的次数。对于字符串中的每个字符,我们使用正则表达式/\w/来判断是否为字母或数字,如果是再进行统计。统计完成后,我们使用Object.keys(count)来获取count对象的键组成的数组,再使用数组的sort方法来排序,使出现次数多的字符排在前面。最后,我们遍历排序后的数组,根据记录的出现次数,使用字符串的repeat方法来生成新字符串
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值