华为OD机试 - 数组合并(Java & JS & Python & C & C++)

一、题目描述

现在有多组整数数组,需要将他们合并成一个新的数组。
合并规则从每个数组里按顺序取出固定长度的内容,合并到新的数组,取完的内容会删除掉。
如果改行不足固定长度,或者已经为空,则直接取出剩余部分的内容放到新的数组中继续下一行。

二、输入描述

第一行,每次读取的固定长度,长度0<len<10;
第二行是整数数组的数目,数目 0<num<10000;
第3~n行是需要合并的数组,不同的数组用换行分割,元素之间用逗号分割,最大不超过100个元素。

三、输出描述

输出一个新的数组,用逗号分割。

四、Java算法源码

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int len = scanner.nextInt(); // 行每次读取的固定长度
    int num = scanner.nextInt(); // 整数数组的数目
    String s = scanner.nextLine(); // nextInt后有空行,先读取一次

    List<List<String>> arrays = new ArrayList<>(num);
    int maxArrayLen = 0;
    int totalLen = 0;
    for (int i = 0; i < num; i++) {
        List<String> array = Arrays.stream(scanner.nextLine().split(",")).collect(Collectors.toList());
        arrays.add(array);
        totalLen += array.size();
        maxArrayLen = Math.max(maxArrayLen, array.size());
    }


    // 计算每个数组最多需要截取几次,即遍历次数
    int cycle;
    if (maxArrayLen % len == 0) {
        cycle = maxArrayLen / len;
    } else {
        cycle = maxArrayLen / len + 1;
    }

    // 拼接结果数组
    List<String> results = new ArrayList<>(totalLen);

    int start;
    int end;
    for (int i = 0; i < cycle; i++) {
        for (List<String> array : arrays) {
            start = i * len;
            end = (i + 1) * len;
            int size = array.size();

            // 如果开始index已经大于数组最大,说明该数组取完了
            if (start > size - 1) {
                continue;
            }

            // 结束index最大为size
            if (end > size) {
                end = size;
            }

            // 取指定长度的子数组
            results.addAll(array.subList(start, end));
        }
    }
    System.out.println(String.join(",", results));
}

五、效果展示

输入:

3
2
2,5,6,7,9,5,7
1,7,4,3,4

输出:

2,5,6,1,7,4,7,9,5,3,4,7

说明:

获得长度3和数组数目2
先遍历第一行 获得2,5,6
再遍历第二行 获得1,7,4
再循环回到第一行获得7,9,5
再遍历第二行获得3,4
再回到第一行获得7

六、JavaScript算法源码

// 导入readline模块以处理标准输入  
const readline = require('readline');  
const rl = readline.createInterface({  
    input: process.stdin,  
    output: process.stdout  
});  
  
// 读取固定长度和整数数组数目的函数  
async function readInput() {  
    return new Promise((resolve, reject) => {  
        rl.question('请输入行每次读取的固定长度: ', (len) => {  
            rl.question('请输入整数数组的数目: ', (num) => {  
                rl.question('请输入空行(nextInt后): ', () => {  
                    resolve({ len: parseInt(len), num: parseInt(num) });  
                });  
            });  
        });  
    });  
}  
  
// 主函数  
async function main() {  
    try {  
        // 读取输入  
        const { len, num } = await readInput();  
        const arrays = [];  
        let maxArrayLen = 0;  
        let totalLen = 0;  
  
        // 读取并处理每个数组  
        for (let i = 0; i < num; i++) {  
            const input = await new Promise(resolve => rl.question('', resolve));  
            const array = input.split(',').map(s => s.trim());  
            arrays.push(array);  
            totalLen += array.length;  
            maxArrayLen = Math.max(maxArrayLen, array.length);  
        }  
  
        // 计算每个数组最多需要截取几次  
        let cycle = Math.ceil(maxArrayLen / len);  
  
        // 拼接结果数组  
        let results = [];  
  
        // 遍历截取次数  
        for (let i = 0; i < cycle; i++) {  
            // 遍历所有数组  
            for (const array of arrays) {  
                let start = i * len;  
                let end = Math.min((i + 1) * len, array.length);  
  
                // 如果开始位置已经大于数组长度,说明该数组已取完  
                if (start > array.length - 1) {  
                    continue;  
                }  
  
                // 取指定长度的子数组  
                results.push(...array.slice(start, end));  
            }  
        }  
  
        // 输出结果  
        console.log(results.join(','));  
  
        // 关闭readline接口  
        rl.close();  
    } catch (error) {  
        console.error('读取输入时出错:', error);  
        rl.close();  
    }  
}  
  
// 调用主函数  
main();

七、Python算法源码

# 导入必要的库  
from typing import List  
  
# 主函数  
def main():  
    # 读取输入的行每次读取的固定长度和整数数组的数目  
    len_value = int(input("请输入行每次读取的固定长度: "))  
    num_arrays = int(input("请输入整数数组的数目: "))  
    input()  # 读取nextInt后的空行  
  
    # 初始化数组列表、最大数组长度和总长度  
    arrays = []  
    max_array_len = 0  
    total_len = 0  
  
    # 读取并处理每个数组  
    for _ in range(num_arrays):  
        array_str = input()  
        array = array_str.split(",")  # 将输入的字符串按逗号分割成列表  
        arrays.append(array)  
        total_len += len(array)  
        max_array_len = max(max_array_len, len(array))  
  
    # 计算每个数组最多需要截取几次,即遍历次数  
    cycle = max_array_len // len_value  
    if max_array_len % len_value != 0:  
        cycle += 1  
  
    # 初始化结果数组  
    results = []  
  
    # 遍历截取次数  
    for i in range(cycle):  
        for array in arrays:  
            start = i * len_value  
            end = (i + 1) * len_value  
            size = len(array)  
  
            # 如果开始index已经大于数组最大,说明该数组取完了  
            if start > size - 1:  
                continue  
  
            # 结束index最大为size  
            if end > size:  
                end = size  
  
            # 取指定长度的子数组  
            results.extend(array[start:end])  
  
    # 输出结果,用逗号连接  
    print(",".join(results))  
  
# 调用主函数  
if __name__ == "__main__":  
    main()

八、C算法源码

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
  
// 定义一个字符串数组的结构体,用于存储二维字符串数组  
typedef struct {  
    char **data;  
    int len;  
} StringArray;  
  
// 函数声明  
StringArray* createStringArray(int size);  
void appendStringToArray(StringArray *array, const char *str);  
void freeStringArray(StringArray *array);  
  
int main(int argc, char *argv[]) {  
    int len, num, i;  
    char buffer[1024]; // 假设输入的每行不会超过1023个字符  
    scanf("%d", &len); // 行每次读取的固定长度  
    scanf("%d", &num); // 整数数组的数目  
    getchar(); // 读取nextInt后的换行符  
  
    StringArray *arrays = (StringArray*)malloc(num * sizeof(StringArray));  
    int maxArrayLen = 0, totalLen = 0;  
    for (i = 0; i < num; i++) {  
        arrays[i] = createStringArray(0); // 初始长度为0  
        fgets(buffer, sizeof(buffer), stdin); // 读取一行  
        char *token = strtok(buffer, ","); // 分割字符串  
        while (token != NULL) {  
            appendStringToArray(&arrays[i], token);  
            token = strtok(NULL, ",");  
        }  
        totalLen += arrays[i].len;  
        maxArrayLen = (maxArrayLen > arrays[i].len) ? maxArrayLen : arrays[i].len;  
    }  
  
    // 计算每个数组最多需要截取几次  
    int cycle = (maxArrayLen % len == 0) ? maxArrayLen / len : maxArrayLen / len + 1;  
  
    // 拼接结果数组  
    char **results = (char**)malloc(totalLen * sizeof(char*));  
    int resultIndex = 0;  
    for (int j = 0; j < cycle; j++) {  
        for (i = 0; i < num; i++) {  
            int start = j * len;  
            int end = (j + 1) * len;  
            if (start > arrays[i].len - 1) {  
                continue;  
            }  
            if (end > arrays[i].len) {  
                end = arrays[i].len;  
            }  
            for (int k = start; k < end; k++) {  
                results[resultIndex++] = strdup(arrays[i].data[k]);  
            }  
        }  
    }  
  
    // 输出结果数组  
    for (i = 0; i < resultIndex; i++) {  
        printf("%s", results[i]);  
        if (i < resultIndex - 1) {  
            printf(",");  
        }  
    }  
    printf("\n");  
  
    // 释放内存  
    for (i = 0; i < num; i++) {  
        freeStringArray(&arrays[i]);  
    }  
    free(arrays);  
    for (i = 0; i < totalLen; i++) {  
        free(results[i]);  
    }  
    free(results);  
  
    return 0;  
}  
  
// 创建字符串数组  
StringArray* createStringArray(int size) {  
    StringArray *array = (StringArray*)malloc(sizeof(StringArray));  
    array->data = (char**)malloc(size * sizeof(char*));  
    array->len = 0;  
    return array;  
}  
  
// 向字符串数组添加字符串  
void appendStringToArray(StringArray *array, const char *str) {  
    array->data[array->len++] = strdup(str);  
}  
  
// 释放字符串数组的内存  
void freeStringArray(StringArray *array) {  
    for (int i = 0; i < array->len; i++) {  
        free(array->data[i]);  
    }  
    free(array->data);  
    free(array);  
}

九、C++算法源码

#include <iostream>  
#include <vector>  
#include <sstream>  
#include <string>  
  
int main() {  
    std::string line;  
    std::getline(std::cin, line); // 读取整行输入  
    std::istringstream iss(line);  
    int len, num;  
    iss >> len; // 行每次读取的固定长度  
    iss >> num; // 整数数组的数目  
    std::getline(std::cin, line); // 读取并忽略nextInt后可能留下的换行符  
  
    std::vector<std::vector<std::string>> arrays(num);  
    int maxArrayLen = 0;  
    int totalLen = 0;  
    for (int i = 0; i < num; ++i) {  
        std::getline(std::cin, line);  
        std::istringstream iss_line(line);  
        std::string item;  
        while (std::getline(iss_line, item, ',')) { // 使用getline和','作为分隔符来分割字符串  
            arrays[i].push_back(item);  
        }  
        totalLen += arrays[i].size();  
        maxArrayLen = std::max(maxArrayLen, static_cast<int>(arrays[i].size()));  
    }  
  
    // 计算每个数组最多需要截取几次,即遍历次数  
    int cycle;  
    if (maxArrayLen % len == 0) {  
        cycle = maxArrayLen / len;  
    } else {  
        cycle = maxArrayLen / len + 1;  
    }  
  
    // 拼接结果数组  
    std::vector<std::string> results;  
    results.reserve(totalLen); // 预留足够的空间  
  
    for (int i = 0; i < cycle; ++i) {  
        for (const auto& array : arrays) {  
            int start = i * len;  
            int end = (i + 1) * len;  
            int size = array.size();  
  
            // 如果开始index已经大于数组最大,说明该数组取完了  
            if (start >= size) {  
                continue;  
            }  
  
            // 结束index最大为size  
            if (end > size) {  
                end = size;  
            }  
  
            // 取指定长度的子数组  
            results.insert(results.end(), array.begin() + start, array.begin() + end);  
        }  
    }  
      
    // 将结果数组转换为逗号分隔的字符串并输出  
    for (size_t i = 0; i < results.size(); ++i) {  
        std::cout << results[i];  
        if (i < results.size() - 1) {  
            std::cout << ",";  
        }  
    }  
    std::cout << std::endl;  
  
    return 0;  
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值