华为OD机试真题 新系统 - API请求日志去重分析 (C/C++/Py/Java/Js/Go)

API请求日志去重分析

华为OD机试真题 华为OD上机考试真题 4月15号 100分题型

华为OD机试真题目录点击查看: 华为OD机试真题题库目录|机考题库 + 算法考点详解

题目描述

某微服务系统的日志监控平台需要分析 API调用记录。日志中包含大量重复的请求记录,为了优化存储和后续分析,需要对相邻的重复请求进行合并统计。

具体规则如下:

1.日志按时间顺序排列,每条记录包含请求路径和响应时间

2.如果连续出现相同的请求路径,需要将这些记录合并为一条

3.合并后的记录需要统计该路径连续出现的次数,并保留所有响应时间的平均值

4.相同路径但被其他路径分隔的,视为不同的记录组,需要分别合并

请实现一个函数,对给定的日志数据进行去重合并处理。

输入描述

输入请求路径path数组,按时间顺序排列

输入对应的响应时间responseTimes数组(毫秒)

补充

  • 0≤paths.length≤10^5
  • 0≤responseTimes.length≤10^5
  • paths.length==responseTimes.length
  • 1≤responseTimes[i]≤10^4
  • 路径长度不超过 100个字符

输出描述

按顺序输出每个记录组信息,每个记录组包含以下三个元素

  • 该路径在输入数组中首次出现索引
  • 该路径连续出现的次数
  • 该组路径的平均响应时间(向下取整)

用例1

输入

none 复制代码
/api/user,/api/user,/api/order,/api/user,/api/order,/api/order
100,200,150,300,250,350

输出

none 复制代码
0,2,150 2,1,150 3,1,300 4,2,300

说明

/api/user在索引0-1连续出现,平均响应时间为150

/api/order在索引2单独出现,平均响应时间为150

api/user在索引3单独出现,由于被分割,响应时间为300

/api/order在索引 4−5 连续出现 2 次,平均响应时间:(250+350)/2=300

题解

思路:双指针

  1. 使用双指针统计每个相同请求地址的{起始位置,终止位置}并累加计算区域内总响应时间。
  2. 根据1的逻辑可以得出每条记录的{首次索引,连续次数,平均响应时间},按顺序保存在结果数组中
  3. 返回结果数组即可

c++

c++ 复制代码
#include<iostream>
#include<vector>
#include<string>
#include <utility> 
#include <sstream>
#include<algorithm> 
#include<cmath>
#include<map>
using namespace std;

// 通用 切割函数 函数 将字符串str根据delimiter进行切割
vector<string> split(const string& str, const string& delimiter) {
    vector<string> result;
    size_t start = 0;
    size_t end = str.find(delimiter);
    while (end != string::npos) {
        result.push_back(str.substr(start, end - start));
        start = end + delimiter.length();
        end = str.find(delimiter, start);
    }
    // 添加最后一个部分
    result.push_back(str.substr(start));
    return result;
}

// 统计函数
vector<vector<int>> hanle(vector<string> path, vector<int> responseTime) {
    vector<vector<int>> res;
    int n = path.size();
    for (int i = 0; i < n; ) {
        int totalTime = responseTime[i];
        int j = i;
        // 获取相同路径起始和终止连续位置
        while (j + 1< n && path[j] == path[j+1]) {
            totalTime += responseTime[j+1];
            j++;
        }
       
        res.push_back({i, j - i + 1, totalTime / (j - i + 1)});
    
        i = j + 1;
    }
    return res;
}

int main() {
    string pathInput;
    string responseInput;
    getline(cin, pathInput);
    getline(cin, responseInput);
    vector<string> paths = split(pathInput, ",");

    vector<int> responseTime(paths.size());
    vector<string> tmp = split(responseInput, ",");
    for (int i = 0; i < tmp.size(); i++) {
        responseTime[i] = stoi(tmp[i]);
    }
    vector<vector<int>> res = hanle(paths, responseTime);
    // 输出结果
    for (int i = 0; i < res.size(); i++) {
        cout << res[i][0] << "," << res[i][1] << "," << res[i][2];
        if (i != res.size() -1) {
            cout << " ";
        }
    }
    return 0;
}

JAVA

JAVA 复制代码
import java.util.*;

public class Main {

    // 统计函数
    static List<int[]> hanle(List<String> path, List<Integer> responseTime) {
        List<int[]> res = new ArrayList<>();
        int n = path.size();

        for (int i = 0; i < n;) {
            int totalTime = responseTime.get(i);
            int j = i;

            // 获取相同路径起始和终止连续位置
            while (j + 1 < n && path.get(j).equals(path.get(j + 1))) {
                totalTime += responseTime.get(j + 1);
                j++;
            }

            res.add(new int[]{i, j - i + 1, totalTime / (j - i + 1)});
            i = j + 1;
        }
        return res;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String pathInput = sc.nextLine();
        String responseInput = sc.nextLine();

        String[] pathsArr = pathInput.split(",");
        String[] responseArr = responseInput.split(",");

        List<String> paths = Arrays.asList(pathsArr);
        List<Integer> responseTime = new ArrayList<>();

        for (String s : responseArr) {
            responseTime.add(Integer.parseInt(s));
        }

        List<int[]> res = hanle(paths, responseTime);

        for (int i = 0; i < res.size(); i++) {
            int[] r = res.get(i);
            System.out.print(r[0] + "," + r[1] + "," + r[2]);
            if (i != res.size() - 1) System.out.print(" ");
        }
    }
}

Python

python 复制代码
import sys

# 统计函数
def hanle(path, response_time):
    res = []
    n = len(path)
    i = 0

    while i < n:
        total_time = response_time[i]
        j = i

        # 获取相同路径起始和终止连续位置
        while j + 1 < n and path[j] == path[j + 1]:
            total_time += response_time[j + 1]
            j += 1

        res.append([i, j - i + 1, total_time // (j - i + 1)])
        i = j + 1

    return res


if __name__ == "__main__":
    path_input = sys.stdin.readline().strip()
    response_input = sys.stdin.readline().strip()

    paths = path_input.split(",")
    response_time = list(map(int, response_input.split(",")))

    res = hanle(paths, response_time)

    print(" ".join(f"{r[0]},{r[1]},{r[2]}" for r in res))

JavaScript

js 复制代码
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let input = [];

rl.on("line", (line) => {
    input.push(line.trim());
});

rl.on("close", () => {
    let pathInput = input[0];
    let responseInput = input[1];

    let paths = pathInput.split(",");
    let responseTime = responseInput.split(",").map(Number);

    function hanle(path, responseTime) {
        let res = [];
        let n = path.length;

        for (let i = 0; i < n;) {
            let totalTime = responseTime[i];
            let j = i;

            // 获取相同路径起始和终止连续位置
            while (j + 1 < n && path[j] === path[j + 1]) {
                totalTime += responseTime[j + 1];
                j++;
            }

            res.push([i, j - i + 1, Math.floor(totalTime / (j - i + 1))]);
            i = j + 1;
        }

        return res;
    }

    let res = hanle(paths, responseTime);

    console.log(res.map(r => `${r[0]},${r[1]},${r[2]}`).join(" "));
});

Go

go 复制代码
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

// 统计函数
func hanle(path []string, responseTime []int) [][]int {
    res := [][]int{}
    n := len(path)

    for i := 0; i < n; {
        totalTime := responseTime[i]
        j := i

        // 获取相同路径起始和终止连续位置
        for j+1 < n && path[j] == path[j+1] {
            totalTime += responseTime[j+1]
            j++
        }

        res = append(res, []int{i, j - i + 1, totalTime / (j - i + 1)})
        i = j + 1
    }

    return res
}

func main() {
    reader := bufio.NewReader(os.Stdin)

 
    pathInput, _ := reader.ReadString('\n')
    responseInput, _ := reader.ReadString('\n')

    // 去掉换行符
    pathInput = strings.TrimSpace(pathInput)
    responseInput = strings.TrimSpace(responseInput)

   
    paths := strings.Split(pathInput, ",")
    tmp := strings.Split(responseInput, ",")

    responseTime := make([]int, len(tmp))
    for i := 0; i < len(tmp); i++ {
        fmt.Sscanf(tmp[i], "%d", &responseTime[i])
    }

    res := hanle(paths, responseTime)

    for i := 0; i < len(res); i++ {
        fmt.Printf("%d,%d,%d", res[i][0], res[i][1], res[i][2])
        if i != len(res)-1 {
            fmt.Print(" ")
        }
    }
}

C语言

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 统计函数
void hanle(char path[][100], int pathSize, int responseTime[],
           int res[][3], int *resSize) {

    int k = 0;

    for (int i = 0; i < pathSize;) {
        int totalTime = responseTime[i];
        int j = i;

        // 获取相同路径起始和终止连续位置
        while (j + 1 < pathSize && strcmp(path[j], path[j + 1]) == 0) {
            totalTime += responseTime[j + 1];
            j++;
        }

        res[k][0] = i;
        res[k][1] = j - i + 1;
        res[k][2] = totalTime / (j - i + 1);
        k++;

        i = j + 1;
    }

    *resSize = k;
}

int main() {
    char pathInput[10300000], responseInput[10300000];
    fgets(pathInput, sizeof(pathInput), stdin);
    fgets(responseInput, sizeof(responseInput), stdin);

    // 去掉换行
    pathInput[strcspn(pathInput, "\n")] = 0;
    responseInput[strcspn(responseInput, "\n")] = 0;

    char path[100005][100];
    int responseTime[100005];

    int pathSize = 0;


    char *token = strtok(pathInput, ",");
    while (token) {
        strcpy(path[pathSize++], token);
        token = strtok(NULL, ",");
    }

    int i = 0;
    token = strtok(responseInput, ",");
    while (token) {
        responseTime[i++] = atoi(token);
        token = strtok(NULL, ",");
    }

    int res[100005][3], resSize = 0;
    hanle(path, pathSize, responseTime, res, &resSize);

    for (int i = 0; i < resSize; i++) {
        printf("%d,%d,%d", res[i][0], res[i][1], res[i][2]);
        if (i != resSize - 1) printf(" ");
    }

    return 0;
}
相关推荐
无限码力4 天前
华为OD技术面真题 - Python开发 - 4
python·华为od·华为od技术面真题·华为od面试八股文·华为od面试真题·华为odpython开发真题·华为od技术面题目
无限码力6 天前
华为OD机试真题 新系统 - 直捣黄龙 (C/C++/Py/Java/Js/Go)
华为od·华为od机试真题·华为od上机考试真题·华为od机考真题·华为od新系统机试真题·华为od4月8号机试真题
无限码力8 天前
华为OD技术面真题 - JAVA开发- spring框架 - 7
java·开发语言·华为od·华为od面试真题·华为odjava八股文·华为odjava开发题目·华为odjava开发高频题目
无限码力22 天前
华为OD机试双机位C卷真题-红黑图(C/C++/Py/Java/Js/Go)
华为od·华为od机试真题·华为od机试双机位c卷·华为od上机考试真题·华为od机考真题·华为od机试-红黑图·华为od机考真题-红黑图
无限码力22 天前
华为OD机试双机位C卷-用户入网定期复评(C/C++/Py/Java/Js/Go)
华为od·华为od机试真题·华为od机试双机位c卷·华为od上机考试真题·华为od机考真题·华为od-用户入网定期复评
gis分享者23 天前
华为OD面试-Java、C++、Pyhton等多语言实现-目录
java·c++·华为od·面试·目录·od·机试
无限码力24 天前
华为OD机试双机位C卷-虚拟文件系统(C/C++/Py/Java/Js/Go)
华为od·华为od机试真题·华为od机试双机位c卷·华为od上机考试真题·华为od机考真题·华为od-虚拟文件系统·华为od机试题库
sprite_雪碧1 个月前
考研机试笔记-1输入输出
笔记·考研·华为od
无限码力1 个月前
华为OD机试真题2026双机位C卷 C++实现【日志解析】
c++·华为od·华为od机试真题·华为od机考真题·华为od机试真题-日志解析