Bootstrap

华为OD机试 - 分界线(Python/JS/C/C++ 2024 E卷 100分)

在这里插入图片描述

2025华为OD机试题库(按算法分类):2025华为OD统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++)

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

电视剧《分界线》里面有一个片段,男主为了向警察透露案件细节,且不暴露自己,于是将报刊上的字剪切下来,剪拼成匿名信。现在有一名举报人,希望借鉴这种手段,使用英文报刊完成举报操作。

但为了增加文章的混淆度,只需满足每个单词中字母数量一致即可,不关注每个字母的顺序解释:单词on允许通过单词’no’进行替代报纸代表newspaper,匿名信代表anonymousLetter,求报纸内容是否可以拼成匿名信。

二、输入描述

第一行输入newspaper内容,包括1-N个字符串,用空格分开
第二行输入anonymousLetter内容,包括1-N个字符串,用空格分开

  1. newspaper和anonymousLetter的字符串由小写英文字母组成且每个字母只能使用一次;
  2. newspaper内容中的每个字符串字母顺序可以任意调整,但必须保证字符串的完整性(每个字符串不能有多余字母);
  3. 1<N<100 , 1<= newspaper.length, anonymousLetter.length <= 104;

三、输出描述

如果报纸可以拼成匿名信返回ture,否则返回false。

四、测试用例

1、输入

ac df
adf

2、输出

false

五、解题思路

  1. 读取输入的报纸内容和匿名信内容。
  2. 将报纸内容和匿名信内容分别以空格为分隔符拆分成字符串数组。
  3. 创建一个HashSet,用于存储报纸内容中每个字符串按字母排序后的值。
  4. 遍历报纸内容数组:
    • 对于每个字符串,将其转换为字符数组,并按字母顺序进行排序。
    • 将排序后的字符数组转换为字符串,并添加到HashSet中。
  5. 创建一个布尔变量flag,并将其初始化为true。
  6. 遍历匿名信内容数组:
    • 对于每个字符串,将其转换为字符数组,并按字母顺序进行排序。
    • 将排序后的字符数组转换为字符串。
    • 如果HashSet中不包含该字符串,则将flag设为false,并跳出循环。
  7. 根据flag的值,输出"true"或"false"表示报纸是否可以拼成匿名信。

该算法的时间复杂度为O(N+M),其中N是报纸内容的长度,M是匿名信内容的长度。因为需要遍历两个字符串数组,对每个字符串进行排序,并将排序后的字符串存储到HashSet中。最终的空间复杂度为O(N),取决于HashSet的存储空间。

六、Python算法源码

# -*- coding: utf-8 -*-
def canFormAnonymousLetter():
    # 读取报纸内容和匿名信内容,并去除两端空白字符
    newspaper = input().strip()
    anonymous = input().strip()
    
    # 按空格分割成单词列表
    words_newspaper = newspaper.split()
    words_anonymous = anonymous.split()
    
    # 使用字典统计报纸中每个单词(字母排序后)的频率
    freq = {}
    for word in words_newspaper:
        sorted_word = ''.join(sorted(word))  # 对单词中的字母排序
        freq[sorted_word] = freq.get(sorted_word, 0) + 1  # 统计该排序后单词的数量
    
    # 遍历匿名信中的每个单词,检查是否能在报纸中匹配
    for word in words_anonymous:
        sorted_word = ''.join(sorted(word))
        if sorted_word not in freq or freq[sorted_word] == 0:
            # 若没有对应单词或数量不足,则返回False
            return False
        else:
            freq[sorted_word] -= 1  # 使用该单词后,数量减1
    return True

# 调用函数并打印结果,转换为小写字符串形式
print(str(canFormAnonymousLetter()).lower())

七、JavaScript算法源码

function canFormAnonymousLetter() {
    // 引入fs模块用于读取标准输入
    const fs = require('fs');
    // 读取全部输入数据并按换行符分割
    let input = fs.readFileSync(0, 'utf-8').trim().split('\n');
    let newspaper = input[0].trim();  // 第一行:报纸内容
    let anonymous = input[1].trim();  // 第二行:匿名信内容
    
    // 按空格分割字符串为单词数组
    let wordsNewspaper = newspaper.split(/\s+/);
    let wordsAnonymous = anonymous.split(/\s+/);
    
    // 使用对象(字典)统计报纸中每个单词(字母排序后)的出现次数
    let freq = {};
    for (let word of wordsNewspaper) {
        // 将单词拆分成字符数组、排序、再合并为字符串
        let sortedWord = word.split('').sort().join('');
        freq[sortedWord] = (freq[sortedWord] || 0) + 1;  // 更新频率
    }
    
    // 遍历匿名信单词,检查每个单词是否有足够的匹配
    for (let word of wordsAnonymous) {
        let sortedWord = word.split('').sort().join('');
        if (!freq[sortedWord] || freq[sortedWord] <= 0) {
            // 若对应单词不存在或数量不足,则返回false
            return false;
        }
        freq[sortedWord]--;  // 使用后数量减1
    }
    return true;
}

// 调用函数并输出结果
console.log(String(canFormAnonymousLetter()));

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 定义最大行长度(根据题目输入范围可适当调整)
#define MAX_LINE_LEN 100000

// 定义最大单词数(题目要求 <= 10^4)
#define MAX_WORDS 10000

// 定义结构体保存单词及其出现次数
typedef struct {
    char *word;  // 存储排序后的单词
    int count;   // 该单词出现的次数
} WordCount;

// 辅助函数:比较两个字符(用于qsort)
int cmpChar(const void *a, const void *b) {
    return (*(char*)a - *(char*)b);
}

// 辅助函数:对字符串中的字母排序,返回排序后的新字符串(需free)
char* sortString(const char *s) {
    int len = strlen(s);
    char *temp = (char*)malloc(len + 1);
    strcpy(temp, s);
    qsort(temp, len, sizeof(char), cmpChar);
    return temp;  // 调用者负责释放内存
}

// 主函数
int main(){
    char line1[MAX_LINE_LEN], line2[MAX_LINE_LEN];
    
    // 读取两行输入
    if(fgets(line1, sizeof(line1), stdin) == NULL) return 1;
    if(fgets(line2, sizeof(line2), stdin) == NULL) return 1;
    
    // 去除末尾可能的换行符
    line1[strcspn(line1, "\n")] = '\0';
    line2[strcspn(line2, "\n")] = '\0';
    
    WordCount freq[MAX_WORDS];  // 存储频率的数组
    int freqSize = 0;  // 当前不同单词的数量
    
    // 使用 strtok 分割报纸行(第一行)
    char *token = strtok(line1, " ");
    while(token != NULL) {
        // 对单词进行排序
        char *sortedWord = sortString(token);
        
        // 在freq数组中查找是否已存在该单词
        int found = 0;
        for (int i = 0; i < freqSize; i++) {
            if(strcmp(freq[i].word, sortedWord) == 0) {
                freq[i].count++;
                found = 1;
                break;
            }
        }
        if(!found) {
            // 若未找到,则添加新的记录
            freq[freqSize].word = sortedWord; // 注意:sortedWord已经分配内存
            freq[freqSize].count = 1;
            freqSize++;
        } else {
            free(sortedWord);  // 已存在,则释放刚分配的内存
        }
        token = strtok(NULL, " ");
    }
    
    int flag = 1;  // 标记是否可以拼出匿名信
    
    // 处理匿名信行(第二行)
    token = strtok(line2, " ");
    while(token != NULL) {
        char *sortedWord = sortString(token);
        int found = 0;
        for (int i = 0; i < freqSize; i++) {
            if(strcmp(freq[i].word, sortedWord) == 0 && freq[i].count > 0) {
                // 找到对应单词且数量足够,扣减数量
                freq[i].count--;
                found = 1;
                break;
            }
        }
        if(!found) {
            flag = 0;  // 无法匹配
            free(sortedWord);
            break;
        }
        free(sortedWord);
        token = strtok(NULL, " ");
    }
    
    // 输出结果
    if(flag)
        printf("true\n");
    else
        printf("false\n");
    
    // 释放freq数组中分配的内存
    for (int i = 0; i < freqSize; i++) {
        free(freq[i].word);
    }
    
    return 0;
}

九、C++算法源码

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

int main(){
    // 读取整行输入
    string line1, line2;
    getline(cin, line1);  // 第一行:报纸内容
    getline(cin, line2);  // 第二行:匿名信内容
    
    // 使用istringstream将字符串按空格分割成单词
    istringstream iss1(line1);
    istringstream iss2(line2);
    
    // 使用unordered_map统计报纸中每个单词(字母排序后)的频率
    unordered_map<string,int> freq;
    string word;
    while(iss1 >> word){
        string sortedWord = word;
        sort(sortedWord.begin(), sortedWord.end());  // 对单词中字母排序
        freq[sortedWord]++;
    }
    
    bool flag = true;
    // 遍历匿名信中的每个单词,尝试匹配报纸中的单词
    while(iss2 >> word){
        string sortedWord = word;
        sort(sortedWord.begin(), sortedWord.end());
        if(freq[sortedWord] > 0){
            freq[sortedWord]--;  // 扣减对应单词数量
        } else {
            flag = false;
            break;
        }
    }
    
    // 输出结果
    cout << (flag ? "true" : "false") << endl;
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

;