华为OD机试 - 数据单元的变量替换 - 分治、递归(Python/JS/C/C++ 2024 E卷 200分)

news2024/9/25 11:06:33

在这里插入图片描述

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

专栏导读

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

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

一、题目描述

将一个csv格式的数据文件Q中包含有单元格引用的内容替换为对应单元格内容的实际值。

Comma seprated values (CSV) 逗号分隔值,csv格式的数据文件使用逗号作为分隔符Q将各单元格的内容进行分隔。

二、输入描述

  1. 输入只有一行数据, 用逗号分隔每个单元格, 行尾没有逗号。最多26个单元格, 对应编号A-Z。
  2. 每个单元格的内容包含字母和数字,以及使用<>分隔的单元格引用,例如: 表示引用第一个单元格的值。
  3. 每个单元格的内容, 在替换前和替换后均不超过100个字符。
  4. 引用单元格的位置不受限制, 运行排在后面的单元格被排在前面的单元格引用。
  5. 不存在循环引用的情况, 比如下面这种场景是不存在的:
    A单元格:aCd8u
    B单元格:kAydzqo
  6. 不存在多重<>的情况, 一个单元格只能引用一个其他单元格。比如下面这种场景是不存在的:
    • A单元格:aCd8u
    • B单元格:kAydzqo
    • C单元格:y<>d

三、输出描述

输出所有单元格展开的内容, 单元格之间用逗号分隔。处理过程中出现错误时, 输出字符串Q "-1"表示出错。

四、测试用例

测试用例1:

1、输入

1,200

2、输出

1,2100

3、说明

第二个单元中有对A单元的引用,A单元格的值为1,替换时,将A单元的内容替代的位置,并和其他内容合并。

测试用例2:

1、输入

12,1

2、输出

112,1

3、说明

第一个单元中有对B单元的引用,B单元格的值为1,替换时,将第二个数据单元的内容替代的位置,并和其他内容合并。

五、解题思路

1、为什么采用递归?

这是基于分治思想的一个简单递归,每次将当前的引用替换为实际内容,然后继续递归解析被引用的单元格,直到没有引用为止。

如果发现某个单元格引用了其他单元格,使用递归调用 resolveReference() 方法来解析引用的单元格内容。

递归确保了即使一个单元格引用了多个层次的单元格(如 A 引用 B,B 引用 C),最终都能解析到实际内容。

2、具体步骤:

  1. 解析输入:
    • 将输入的CSV数据按照逗号分割成一个字符串数组,每个字符串代表一个单元格的内容。根据题意,最多有26个单元格,对应A-Z。
  2. 查找并替换引用:
    • 对每个单元格的内容进行遍历,检查其中是否包含<>,如果包含说明引用了其他单元格。
    • 引用的形式为、等形式,意味着需要将该单元格的内容替换为对应引用单元格的实际内容。
    • 使用一个循环替换引用,确保所有引用的单元格内容被正确替换。
  3. 检测错误:
    • 需要考虑到输入数据的合法性,比如引用的单元格是否存在,以及是否引用内容超过100个字符。如果出现错误,输出"-1"。
  4. 输出结果:
    • 所有的单元格内容展开后,按照CSV的格式输出,单元格之间用逗号分隔。

3、时间复杂度

假设每个单元格内容的最大长度为 L,单元格数量为 n,遍历并处理每个单元格的时间复杂度为 O(n * L)。在最坏情况下,所有单元格都有引用关系时,递归的深度最多为 n,因此整体时间复杂度为 O(n^2 * L)。

六、Python算法源码

def replace_cell_references(input_str):
    # 分割输入数据,得到单元格内容
    cells = input_str.split(",")
    # 检查单元格数量是否超过26个
    if len(cells) > 26:
        return "-1"

    # 用一个数组来存储每个单元格的最终值
    results = [None] * 26

    # 进行单元格引用替换的过程
    for i in range(len(cells)):
        results[i] = resolve_reference(cells, i)
        # 如果有错误(-1),则返回错误结果
        if results[i] == "-1":
            return "-1"

    # 拼接结果为CSV格式输出
    return ",".join(filter(None, results[:len(cells)]))


def resolve_reference(cells, index):
    cell_content = cells[index]
    # 查找引用的标识
    start = cell_content.find("<")
    end = cell_content.find(">")

    # 如果找到<>符号,进行引用替换
    if start != -1 and end != -1 and end > start + 1:
        # 获取被引用的单元格编号 (A-Z -> 0-25)
        referenced_cell = cell_content[start + 1]
        if referenced_cell < 'A' or referenced_cell > 'Z':
            return "-1"  # 引用不合法
        ref_index = ord(referenced_cell) - ord('A')  # 转换为索引
        if ref_index >= len(cells):
            return "-1"  # 引用单元格不存在

        # 获取引用的单元格的实际内容
        referenced_content = resolve_reference(cells, ref_index)
        if referenced_content == "-1":
            return "-1"  # 如果引用内容有问题

        # 将引用内容替换到当前单元格
        cell_content = cell_content[:start] + referenced_content + cell_content[end + 1:]

    # 检查单元格内容是否超过100字符
    if len(cell_content) > 100:
        return "-1"  # 内容过长

    return cell_content


def main():
    # 从控制台读取输入
    input_str = input("请输入CSV内容:")  # 从控制台读取输入

    # 调用方法进行单元格引用替换
    result = replace_cell_references(input_str)

    # 输出结果
    print(result)


if __name__ == "__main__":
    main()

七、JavaScript算法源码

function replaceCellReferences(input) {
    // 分割输入数据,得到单元格内容
    let cells = input.split(",");
    // 检查单元格数量是否超过26个
    if (cells.length > 26) {
        return "-1";
    }

    // 用一个数组来存储每个单元格的最终值
    let results = new Array(26).fill(null);

    // 进行单元格引用替换的过程
    for (let i = 0; i < cells.length; i++) {
        results[i] = resolveReference(cells, i);
        // 如果有错误(-1),则返回错误结果
        if (results[i] === "-1") {
            return "-1";
        }
    }

    // 拼接结果为CSV格式输出
    return results.filter(result => result !== null).join(",");
}

function resolveReference(cells, index) {
    let cellContent = cells[index];
    // 查找引用的标识
    let start = cellContent.indexOf("<");
    let end = cellContent.indexOf(">");

    // 如果找到<>符号,进行引用替换
    if (start !== -1 && end !== -1 && end > start + 1) {
        // 获取被引用的单元格编号 (A-Z -> 0-25)
        let referencedCell = cellContent.charAt(start + 1);
        if (referencedCell < 'A' || referencedCell > 'Z') {
            return "-1";  // 引用不合法
        }
        let refIndex = referencedCell.charCodeAt(0) - 'A'.charCodeAt(0); // 转换为索引
        if (refIndex >= cells.length) {
            return "-1";  // 引用单元格不存在
        }

        // 获取引用的单元格的实际内容
        let referencedContent = resolveReference(cells, refIndex);
        if (referencedContent === "-1") {
            return "-1";  // 如果引用内容有问题
        }

        // 将引用内容替换到当前单元格
        cellContent = cellContent.substring(0, start) + referencedContent + cellContent.substring(end + 1);
    }

    // 检查单元格内容是否超过100字符
    if (cellContent.length > 100) {
        return "-1";  // 内容过长
    }

    return cellContent;
}

// 从用户输入读取CSV内容
function main() {
    const input = prompt("请输入CSV内容:");  // 获取用户输入

    // 调用方法进行单元格引用替换
    const result = replaceCellReferences(input);

    // 输出结果
    console.log(result);
}

main();

八、C算法源码

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

#define MAX_CELLS 26
#define MAX_CONTENT 101

// 解析引用内容的函数声明
char* resolveReference(char* cells[], int index, int numCells);

char* replaceCellReferences(char* input) {
    // 分割输入数据,得到单元格内容
    char* cells[MAX_CELLS];
    char* token = strtok(input, ",");
    int numCells = 0;

    // 将输入拆分为各个单元格
    while (token != NULL) {
        if (numCells >= MAX_CELLS) {
            return "-1";  // 超过26个单元格,返回错误
        }
        cells[numCells++] = token;
        token = strtok(NULL, ",");
    }

    // 用一个数组来存储每个单元格的最终值
    char* results[MAX_CELLS];

    // 进行单元格引用替换的过程
    for (int i = 0; i < numCells; i++) {
        results[i] = resolveReference(cells, i, numCells);
        if (strcmp(results[i], "-1") == 0) {
            return "-1";  // 如果有错误,返回错误结果
        }
    }

    // 拼接结果为CSV格式
    static char result[MAX_CONTENT * MAX_CELLS] = {0};
    for (int i = 0; i < numCells; i++) {
        strcat(result, results[i]);
        if (i < numCells - 1) {
            strcat(result, ",");
        }
    }

    return result;
}

// 解析引用内容的函数
char* resolveReference(char* cells[], int index, int numCells) {
    static char buffer[MAX_CONTENT];
    strcpy(buffer, cells[index]);

    // 查找引用的标识
    char* start = strchr(buffer, '<');
    char* end = strchr(buffer, '>');

    // 如果找到<>符号,进行引用替换
    if (start != NULL && end != NULL && end > start + 1) {
        char referencedCell = *(start + 1);
        if (referencedCell < 'A' || referencedCell > 'Z') {
            return "-1";  // 引用不合法
        }
        int refIndex = referencedCell - 'A';  // 转换为索引
        if (refIndex >= numCells) {
            return "-1";  // 引用单元格不存在
        }

        // 获取引用的单元格的实际内容
        char* referencedContent = resolveReference(cells, refIndex, numCells);
        if (strcmp(referencedContent, "-1") == 0) {
            return "-1";  // 如果引用内容有问题
        }

        // 将引用内容替换到当前单元格
        strncpy(start, referencedContent, end - start + 1);
        strcpy(start + strlen(referencedContent), end + 1);
    }

    // 检查单元格内容是否超过100字符
    if (strlen(buffer) > 100) {
        return "-1";  // 内容过长
    }

    return buffer;
}

int main() {
    char input[256];
    printf("请输入CSV内容:");
    fgets(input, sizeof(input), stdin);
    input[strcspn(input, "\n")] = 0;  // 去掉换行符

    // 调用方法进行单元格引用替换
    char* result = replaceCellReferences(input);

    // 输出结果
    printf("%s\n", result);

    return 0;
}

九、C++算法源码

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

#define MAX_CELLS 26
#define MAX_CONTENT 101

using namespace std;

// 解析引用内容的函数声明
string resolveReference(vector<string>& cells, int index, int numCells);

string replaceCellReferences(string input) {
    // 分割输入数据,得到单元格内容
    vector<string> cells;
    string token;
    stringstream ss(input);

    // 使用逗号分割字符串
    while (getline(ss, token, ',')) {
        cells.push_back(token);
    }

    // 检查单元格数量是否超过26个
    if (cells.size() > MAX_CELLS) {
        return "-1";
    }

    // 用一个数组来存储每个单元格的最终值
    vector<string> results(MAX_CELLS);

    // 进行单元格引用替换的过程
    for (int i = 0; i < cells.size(); i++) {
        results[i] = resolveReference(cells, i, cells.size());
        // 如果有错误,返回错误结果
        if (results[i] == "-1") {
            return "-1";
        }
    }

    // 拼接结果为CSV格式
    string result;
    for (int i = 0; i < cells.size(); i++) {
        result += results[i];
        if (i < cells.size() - 1) {
            result += ",";
        }
    }

    return result;
}

// 解析引用内容的函数
string resolveReference(vector<string>& cells, int index, int numCells) {
    string cellContent = cells[index];

    // 查找引用的标识
    size_t start = cellContent.find("<");
    size_t end = cellContent.find(">");

    // 如果找到<>符号,进行引用替换
    if (start != string::npos && end != string::npos && end > start + 1) {
        char referencedCell = cellContent[start + 1];
        if (referencedCell < 'A' || referencedCell > 'Z') {
            return "-1";  // 引用不合法
        }
        int refIndex = referencedCell - 'A';  // 转换为索引
        if (refIndex >= numCells) {
            return "-1";  // 引用单元格不存在
        }

        // 获取引用的单元格的实际内容
        string referencedContent = resolveReference(cells, refIndex, numCells);
        if (referencedContent == "-1") {
            return "-1";  // 如果引用内容有问题
        }

        // 将引用内容替换到当前单元格
        cellContent.replace(start, end - start + 1, referencedContent);
    }

    // 检查单元格内容是否超过100字符
    if (cellContent.length() > MAX_CONTENT - 1) {
        return "-1";  // 内容过长
    }

    return cellContent;
}

int main() {
    string input;
    cout << "请输入CSV内容:";
    getline(cin, input);  // 从控制台读取输入

    // 调用方法进行单元格引用替换
    string result = replaceCellReferences(input);

    // 输出结果
    cout << result << endl;

    return 0;
}


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

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

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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2163380.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于yolov8+deepsort+gradio实现目标追踪演示

【效果展示】 【测试环境】 ultralytics8.2.95 gradio4.26.0 torch1.9.0cu111 理论上支持最新ultralytics版本 【实现部分代码】 with gr.Blocks() as demo:with gr.Tab("追踪"):# 使用Markdown显示文本信息&#xff0c;介绍界面的功能gr.Markdown(""…

linux固定串口别名

最近项目功能要求&#xff0c;需要将插入设备的串口设备占用的端口号固定住&#xff0c;这里记录一下设置过程方便以后查阅。 linux固定串口别名 配置过程相关补充 配置过程 列出当前插入USB端口的设备&#xff1a; lsusb查看当前设备的端口号&#xff1a; ls dev/查看当前设…

无人机飞手培训及巡检、吊运等飞行服务一体化技术详解

在无人机行业日益兴起的背景下&#xff0c;培养专业、合格的无人机飞手成为首要任务。飞手培训基础涵盖理论学习与安全意识建立两大方面。理论学习包括无人机基础知识&#xff08;如无人机类型、结构、原理&#xff09;、航空法规&#xff08;如民用无人驾驶航空器实名制登记管…

旧衣回收小程序搭建,开发功能优势

随着人们生活水平、消费水平的提高&#xff0c;在日常生活中产生了大量的限制物品&#xff0c;为了减少浪费&#xff0c;越来越多的人开始重视环保回收。旧衣物作为一种新型的回收方式&#xff0c;也逐渐得到了大众的关注&#xff0c;旧衣物回收市场发展规模也在持续上升&#…

Certbot自动申请并续期https证书

Certbot自动申请并续期https证书 一、 安装 Certbot&#xff1a;使用命令安装 Certbot&#xff1a; dnf install certbot python3-certbot-nginx获取 SSL 证书&#xff1a;运行 Certbot 命令来获取并安装 SSL 证书。 示例命令&#xff0c;替换其中的域名和路径信息&#xff1a…

PHP API 框架:构建高效API的利器【电商API接口】

在当今快速发展的互联网时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为连接不同应用程序和服务的关键。PHP&#xff0c;作为一种流行的服务器端脚本语言&#xff0c;提供了多种强大的框架来简化API的开发。本文将介绍PHP API框架的重要性&#xff0c;以及…

java并发编程笔记 之 线程和进程

文章目录 前言线程线程优先级和时间片创建多线程及运行线程的状态 进程查看进程的命令进程的通信方式 线程和进程的区别从关系上疑问集锦 前言 并发 1、并发是指在同一时间段内&#xff0c;计算机系统能够处理多个任务的能力。 2、在并发编程中&#xff0c;我们可以理解为多个…

chapter17-多线程基础——(自定义泛型)——day20

580-程序进程线程 581-并发并行 并发和并行也可以同时进行 582-继承Thread创建线程 583-多线程机制 主线程和子线程交替执行 单核&#xff1a;两个线程并发 多核&#xff1a;两个线程并行 主线程结束&#xff0c;不是说进程就结束&#xff0c;进程要等所有线程结束 584-为什…

模型Alignment之RLHF与DPO

1. RLHF (Reinforcement Learning from Human Feedback) RLHF 是一种通过人类反馈来强化学习的训练方法&#xff0c;它能够让语言模型更好地理解和执行人类指令。 RLHF 的三个阶段 RLHF 的训练过程一般分为三个阶段&#xff1a; 监督微调&#xff08;Supervised Fine-Tuning,…

认知杂谈82《跳出信息茧房,持续精进》

内容摘要&#xff1a; 互联网时代&#xff0c;信息丰富&#xff0c;但便捷性削弱了我们的好奇心。互联网是双刃剑&#xff0c;快速获取知识的同时&#xff0c;也让我们陷入“信息茧房”&#xff0c;限制视野。 好奇心减少&#xff0c;部分原因是互联网的“懒惰效应”&#xff0…

国家标准和团体标准有什么区别?

国家标准和团体标准的区别主要体现在以下几个方面&#xff1a; 1. 制定标准的主体不同&#xff1a;国家标准是由国家机构通过并公开发布的标准&#xff1b;团体标准是由学会、协会、商会、联合会、产业技术联盟等社会团体协调相关市场主体共同制…

【项目实战】如何在项目中基于 Spring Boot Starter 开发简单的 SDK

什么是SDK 通常在分布式项目中&#xff0c;类和方法是不能跨模块使用的。为了方便开发者的调用&#xff0c;我们需要开发一个简单易用的SDK&#xff0c;使开发者只需关注调用哪些接口、传递哪些参数&#xff0c;就像调用自己编写的代码一样简单。实际上&#xff0c;RPC(远程过…

element下拉框联动 或 多选 回显数据后页面操作不生效问题解决

第一种:多选回显不生效 解决方式: 代码: <el-form-item label"系统" prop"Key"> <el-select v-model"addForm.Key" multiple placeholder"请选择" change"$forceUpdate()"> <el-option v-for"item …

Typescript高级用法

TypeScript 是一种类型安全的 JavaScript 超集&#xff0c;除了基本类型和对象类型之外&#xff0c;TypeScript 还提供了一些高级类型系统&#xff0c;使得我们可以更好地处理复杂的数据结构和业务逻辑。本文将深入探讨 TypeScript 的高级类型系统&#xff0c;以更好地理解和使…

【AI大模型应用开发】【综合实战】AI+搜索,手把手带你实现属于你的AI搜索引擎(附完整代码)

现在市面上有很多的AI搜索的应用或插件&#xff0c;一直想学习其背后的实现原理。今天咱们就学习一下&#xff0c;并且亲自动手实践&#xff0c;从0开始&#xff0c;搭建一个自己的AI搜索引擎。最终实现效果如下&#xff1a; 话不多说&#xff0c;开干。 本文代码参考&#xff…

累加求和-C语言

1.问题&#xff1a; 计算123……100的和&#xff0c;要求分别用while、do while、for循环实现。 2.解答&#xff1a; 累加问题&#xff0c;先后将100个数相加。要重复进行100次加法运算&#xff0c;可以用循环结构来实现。重复执行循环体100次&#xff0c;每次加一个数。 3.代…

02DSP学习-了解syscfg

不是哥们儿&#xff0c;学习DSP为什么不是上来就写代码啊&#xff0c;说了一堆&#xff0c;写小说呢啊&#xff1f; 你别着急&#xff0c;学习DSP本身&#xff0c;真不需要写多少代码&#xff0c;我们需要的写的是自己的算法。开车知道方向盘、油门、刹车、后视镜之后也能开&a…

【SpringBoot详细教程】-03-整合Junit【持续更新】

JUnit是一个用于Java编程语言的测试框架。它支持自动化单元测试&#xff0c;可以帮助开发人员测试代码的正确性和健壮性。JUnit提供了一组注解、断言和测试运行器&#xff0c;可以方便地编写和运行单元测试。 SpringBoot 整合 junit 特别简单&#xff0c;分为以下三步完成 在…

cmake--file

教程 参数 需要指定文件后缀 GLOB 只搜索当前目录 GLOB_RECURSE &#xff1a;搜索当前目录和其子目录&#xff08;递归搜索&#xff09; RELATIVE 相对于哪个路径进行搜索&#xff0c;获取文件的相对路径。 使用RELATIVE和不使用RELATIVE的区别&#xff1a; 1&#xff…

《让手机秒变超级电脑!ToDesk云电脑、易腾云、青椒云移动端深度体验》

前言 科技发展到如今2024年&#xff0c;可以说每一年都在发生翻天覆地的变化。云电脑这个市场近年来迅速发展&#xff0c;无需购买和维护额外的硬件就可以体验到电脑端顶配的性能和体验&#xff0c;并且移动端也可以带来非凡体验。我们在外出办公随身没有携带电脑情况下&#x…