华为OD机试真题 - 中文分词模拟器(Python/JS/C/C++ 2024 D卷 100分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

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

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

一、题目描述

给定一个连续不包含空格字符的字符串,该字符串仅包含英文小写字母及英文标点符号(逗号、句号、分号),同时给定词库,对该字符串进行精确分词。

说明:

  • 精确分词:字符串分词后,不会出现重叠。例如 “ilovechina”,不同切分后可得到 “i”, “love”, “china”。
  • 标点符号不分词,仅用于断句。
  • 词库:根据常识及词库统计出来的常用词汇。例如:dictionary={“i”,“love”,“china”,“ilovechina”,“lovechina”}。
  • 分词原则:采用分词顺序优先且最长匹配原则。“ilovechina”,假设分词结果[i,ilove,lo,love,ch,china,lovechina] 则输出 [ilove,china]
    • 错误输出:[i, lovechina],原因:“ilove” > 优先于 “lovechina” 成词。
    • 错误输出:[i, love, china],原因:“ilove” > “i”,遵循最长匹配原则。

二、输入描述

  1. 字符串长度限制:0 < length < 256
  2. 词库长度限制:0 < length < 100000
  3. 第一行输入待分词语句 “ilovechina”
  4. 第二行输入中文词库 “i, love, china, ch, na, ve, lo, this, is, the, word”

三、输出描述

按顺序输出分词结果 “i, love, china”

1、输入

ilovechina
i,love,china,ch,na,ve,lo,this,is,the,word

2、输出

i,love,china

3、说明

输入的字符串被按最长匹配原则分为 “i”, “love”, “china”。

四、测试用例

1、输入

ilovech
i,love,china,ch,na,ve,lo,this,is,the,word

2、输出

i,love,ch

3、说明

输入的字符串被按最长匹配原则分为 “i”, “love”, “ch”。

五、解题思路

  1. 解析输入:
    • 读取待分词的字符串。
    • 读取词库,并将其转换为一个集合(Set),以便于快速查找。
  2. 处理标点符号:
    • 标点符号仅用于断句,不参与分词。可以使用正则表达式将字符串按标点符号分割。
  3. 分词处理:
    • 对每个子字符串进行分词,遵循最长匹配原则。
    • 从字符串的第一个字符开始,尝试匹配最长的单词,如果匹配成功,将该单词加入结果集,继续处理剩下的部分。
  4. 输出结果:
    • 将所有子字符串的分词结果组合起来,并按要求格式输出。

六、Python算法源码

import re

def segment(sentence, dictionary):
    result = []
    length = len(sentence)
    start = 0

    while start < length:
        longest_word = None

        # 从当前起始位置向后查找
        for end in range(start + 1, length + 1):
            word = sentence[start:end]

            if word in dictionary:
                if longest_word is None or len(word) > len(longest_word):
                    longest_word = word

        if longest_word is not None:
            result.append(longest_word)
            start += len(longest_word)
        else:
            start += 1

    return result

def main():
    # 读取待分词语句
    input_string = input("请输入待分词语句:")

    # 读取词库
    dictionary_input = input("请输入词库:")

    # 将词库字符串解析成集合,方便后续查找
    dictionary = set(dictionary_input.split(","))

    # 使用正则表达式按标点符号将输入字符串分割成多个子字符串
    sentences = re.split(r'[,.]', input_string)

    # 存储分词结果
    result = []

    # 对每个子字符串进行分词处理
    for sentence in sentences:
        result.extend(segment(sentence.strip(), dictionary))

    # 按要求格式输出分词结果
    print(", ".join(result))

if __name__ == "__main__":
    main()

七、JavaScript算法源码

function segment(sentence, dictionary) {
    const result = [];
    const length = sentence.length;
    let start = 0;

    while (start < length) {
        let longestWord = null;

        // 从当前起始位置向后查找
        for (let end = start + 1; end <= length; end++) {
            const word = sentence.substring(start, end);

            if (dictionary.has(word)) {
                if (longestWord === null || word.length > longestWord.length) {
                    longestWord = word;
                }
            }
        }

        if (longestWord !== null) {
            result.push(longestWord);
            start += longestWord.length;
        } else {
            start += 1;
        }
    }

    return result;
}

function main() {
    // 读取待分词语句
    const input = prompt("请输入待分词语句:");

    // 读取词库
    const dictionaryInput = prompt("请输入词库:");

    // 将词库字符串解析成集合,方便后续查找
    const dictionary = new Set(dictionaryInput.split(","));

    // 使用正则表达式按标点符号将输入字符串分割成多个子字符串
    const sentences = input.split(/[,.;]/);

    // 存储分词结果
    const result = [];

    // 对每个子字符串进行分词处理
    for (const sentence of sentences) {
        result.push(...segment(sentence.trim(), dictionary));
    }

    // 按要求格式输出分词结果
    console.log(result.join(", "));
}

// 调用主函数
main();

八、C算法源码

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

#define MAX_WORD_LENGTH 100
#define MAX_SENTENCE_LENGTH 1000
#define MAX_DICTIONARY_SIZE 100

// 字符串切割函数,类似于Python的split()
char** split(const char* str, const char* delim, int* count) {
    char* str_copy = strdup(str); // 复制字符串,以免修改原字符串
    char* token = strtok(str_copy, delim);
    char** result = malloc(MAX_SENTENCE_LENGTH * sizeof(char*));
    *count = 0;

    while (token != NULL) {
        result[(*count)++] = strdup(token);
        token = strtok(NULL, delim);
    }

    free(str_copy);
    return result;
}

// 判断词库中是否包含某个单词
int is_in_dictionary(char* word, char dictionary[MAX_DICTIONARY_SIZE][MAX_WORD_LENGTH], int dict_size) {
    for (int i = 0; i < dict_size; i++) {
        if (strcmp(word, dictionary[i]) == 0) {
            return 1;
        }
    }
    return 0;
}

// 分词函数,遵循最长匹配原则
void segment(char* sentence, char dictionary[MAX_DICTIONARY_SIZE][MAX_WORD_LENGTH], int dict_size, char result[MAX_SENTENCE_LENGTH][MAX_WORD_LENGTH], int* result_count) {
    int length = strlen(sentence);
    int start = 0;
    *result_count = 0;

    while (start < length) {
        char longest_word[MAX_WORD_LENGTH] = "";
        int longest_length = 0;

        for (int end = start + 1; end <= length; end++) {
            char word[MAX_WORD_LENGTH];
            strncpy(word, sentence + start, end - start);
            word[end - start] = '\0';

            if (is_in_dictionary(word, dictionary, dict_size) && strlen(word) > longest_length) {
                strcpy(longest_word, word);
                longest_length = strlen(word);
            }
        }

        if (longest_length > 0) {
            strcpy(result[*result_count], longest_word);
            (*result_count)++;
            start += longest_length;
        } else {
            start++;
        }
    }
}

int main() {
    char input[MAX_SENTENCE_LENGTH];
    char dictionary_input[MAX_SENTENCE_LENGTH];
    char dictionary[MAX_DICTIONARY_SIZE][MAX_WORD_LENGTH];
    int dict_size = 0;

    // 读取待分词语句
    printf("请输入待分词语句:\n");
    fgets(input, MAX_SENTENCE_LENGTH, stdin);
    input[strcspn(input, "\n")] = '\0';  // 去除换行符

    // 读取词库
    printf("请输入词库:\n");
    fgets(dictionary_input, MAX_SENTENCE_LENGTH, stdin);
    dictionary_input[strcspn(dictionary_input, "\n")] = '\0';  // 去除换行符

    // 将词库字符串解析成二维数组
    int word_count;
    char** words = split(dictionary_input, ",", &word_count);
    for (int i = 0; i < word_count; i++) {
        strcpy(dictionary[dict_size++], words[i]);
        free(words[i]);
    }
    free(words);

    // 使用标点符号将输入字符串分割成多个子字符串
    int sentence_count;
    char** sentences = split(input, ",.;", &sentence_count);

    // 存储分词结果
    char result[MAX_SENTENCE_LENGTH][MAX_WORD_LENGTH];
    int result_count;

    // 对每个子字符串进行分词处理
    for (int i = 0; i < sentence_count; i++) {
        segment(sentences[i], dictionary, dict_size, result, &result_count);

        for (int j = 0; j < result_count; j++) {
            if (i > 0 || j > 0) {
                printf(", ");
            }
            printf("%s", result[j]);
        }
        free(sentences[i]);
    }
    free(sentences);

    printf("\n");
    return 0;
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <cstring>
#include <algorithm>

using namespace std;

// 字符串分割函数,类似于Python的split()
vector<string> split(const string &str, const string &delim) {
    vector<string> tokens;
    size_t prev = 0, pos = 0;

    do {
        pos = str.find_first_of(delim, prev);
        if (pos == string::npos) pos = str.length();
        string token = str.substr(prev, pos - prev);
        if (!token.empty()) tokens.push_back(token);
        prev = pos + 1;
    } while (pos < str.length() && prev < str.length());

    return tokens;
}

// 判断词库中是否包含某个单词
bool is_in_dictionary(const string &word, const vector<string> &dictionary) {
    return find(dictionary.begin(), dictionary.end(), word) != dictionary.end();
}

// 分词函数,遵循最长匹配原则
vector<string> segment(const string &sentence, const vector<string> &dictionary) {
    vector<string> result;
    size_t length = sentence.length();
    size_t start = 0;

    while (start < length) {
        string longest_word;
        size_t longest_length = 0;

        for (size_t end = start + 1; end <= length; ++end) {
            string word = sentence.substr(start, end - start);

            if (is_in_dictionary(word, dictionary) && word.length() > longest_length) {
                longest_word = word;
                longest_length = word.length();
            }
        }

        if (!longest_word.empty()) {
            result.push_back(longest_word);
            start += longest_length;
        } else {
            start++;
        }
    }

    return result;
}

int main() {
    string input;
    string dictionary_input;

    // 读取待分词语句
    cout << "请输入待分词语句:" << endl;
    getline(cin, input);

    // 读取词库
    cout << "请输入词库:" << endl;
    getline(cin, dictionary_input);

    // 将词库字符串解析成集合,方便后续查找
    vector<string> dictionary = split(dictionary_input, ",");

    // 使用标点符号将输入字符串分割成多个子字符串
    vector<string> sentences = split(input, ",.;");

    // 存储分词结果
    vector<string> result;

    // 对每个子字符串进行分词处理
    for (const string &sentence : sentences) {
        vector<string> segmented = segment(sentence, dictionary);
        result.insert(result.end(), segmented.begin(), segmented.end());
    }

    // 按要求格式输出分词结果
    for (size_t i = 0; i < result.size(); ++i) {
        if (i > 0) {
            cout << ", ";
        }
        cout << result[i];
    }
    cout << endl;

    return 0;
}


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

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

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

在这里插入图片描述

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
通信误码是通信过程中由于噪声、信号衰减或其他干扰因素引起的信号错误。解决通信误码的问题是通信领域中非常重要的一项任务。下面是我基于Python的解答: 首先,我们需要定义一个函数来计算两个二进制数字之间的汉明距离,即不同位置的比特数。可以通过将两个二进制数字进行逐位比较来实现。如果两个比特值不同,则汉明距离加1。代码如下: ```python def hamming_distance(bin_1, bin_2): distance = 0 for i in range(len(bin_1)): if bin_1[i] != bin_2[i]: distance += 1 return distance ``` 接下来,我们需要通过输入的二进制数字列表来判断是否存在误码。可以使用两个嵌套的循环来比较所有的数字对,并使用汉明距离函数计算它们之间的距离。如果距离小于等于1,则存在误码。代码如下: ```python def check_error_codes(bin_list): n = len(bin_list) for i in range(n-1): for j in range(i+1, n): distance = hamming_distance(bin_list[i], bin_list[j]) if distance <= 1: return True return False ``` 最后,我们可以编写一个简单的主程序来测试上述函数。首先,从用户输入中获取二进制数字列表,然后调用`check_error_codes`函数来检查是否存在误码。根据检查结果,输出相应的提示信息。代码如下: ```python if __name__ == "__main__": bin_list = input("请输入二进制数字列表,以逗号隔:") bin_list = bin_list.split(",") has_error_codes = check_error_codes(bin_list) if has_error_codes: print("存在误码") else: print("不存在误码") ``` 这样,我们就可以使用上述代码来检查给定的二进制数字列表中是否存在误码。希望这个解答能够帮助你理解该问题的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值