欢迎光临
我们一直在努力

华为OD机试真题 新系统【日志关键词统计】

日志关键词统计(C/C++/Py/Java/Js/Go)题解

华为OD机试新系统真题 华为OD上机考试新系统真题 6月21号 100分题型

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

题目内容

给定日志字符串数组

l

o

g

s

logs

logs 和关键词数组

k

e

y

w

o

r

d

s

keywords

keywords,统计每个关键词在所有日志中出现的总次数,并找出经常一起出现的关键词组合(至少在

2

2

2 条日志中同时出现)。

注意:

  • 关键词匹配大小写不敏感,完整单词匹配(不能是部分匹配)
  • 单词边界:空格、标点符号(逗号、句号、感叹号、问号、分号、冒号)或字符串首尾,英文标点,无中文标点
  • 关联组合:两个关键词在至少

    2

    2

    2 条不同日志中同时出现才算"经常关联"

  • 返回结果:前

    k

    e

    y

    w

    o

    r

    d

    s

    .

    l

    e

    n

    g

    t

    h

    keywords.length

    keywords.length 个元素为关键词出现次数,后续元素每两个一组表示关联组合索引(索引小的在前,索引大的在后);多个组合时先按第一个索引升序,再按第二个索引升序

  • 数据规模:

    1

    l

    o

    g

    s

    1 \\le logs

    1logs.length

    1000

    \\le 1000

    1000

    1

    k

    e

    y

    w

    o

    r

    d

    s

    1 \\le keywords

    1keywords.length

    100

    \\le 100

    100,每条日志长度

    1000

    \\le 1000

    1000 字符

    输入描述

    第一行输入n m,其中n表示日志数量.m表示关键词数量

    接下来n行,每行代表一条日志

    接下来m行,每行代表一条关键词

    输出描述

    输出结果,使用,进行分割。

    样例1

    输入

    3 2
    Error in system
    warning: error detected
    No errors found
    error
    warning

    输出

    2,1

    说明 关键词统计:

    e

    r

    r

    o

    r

    error

    error 出现

    2

    2

    2 次,

    w

    a

    r

    n

    i

    n

    g

    warning

    warning 出现

    1

    1

    1 次 关联分析:

    e

    r

    r

    o

    r

    error

    error

    w

    a

    r

    n

    i

    n

    g

    warning

    warning 只在第

    2

    2

    2 条日志中同时出现

    1

    1

    1 次,未达到至少

    2

    2

    2 次共现的标准,因此无关联组合输出

    样例2

    输入

    4 4
    Error: system failure
    Warning: error in network
    System error detected again
    Network warning error found
    error
    system
    warning
    network

    输出

    4,2,2,2,0,1,0,2,0,3,2,3

    说明 关键词统计:

    e

    r

    r

    o

    r

    error

    error 出现

    4

    4

    4 次,

    s

    y

    s

    t

    e

    m

    system

    system 出现

    2

    2

    2 次,

    w

    a

    r

    n

    i

    n

    g

    warning

    warning 出现

    2

    2

    2 次,

    n

    e

    t

    w

    o

    r

    k

    network

    network 出现

    2

    2

    2 次 关联组合:

    • (

      e

      r

      r

      o

      r

      ,

      s

      y

      s

      t

      e

      m

      error, system

      error,system):在第

      1

      1

      1

      3

      3

      3 条日志中同时出现,共现

      2

      2

      2

      输出

      [

      0

      ,

      1

      ]

      [0,1]

      [0,1]

    • (

      e

      r

      r

      o

      r

      ,

      w

      a

      r

      n

      i

      n

      g

      error, warning

      error,warning):在第

      2

      2

      2

      4

      4

      4 条日志中同时出现,共现

      2

      2

      2

      输出

      [

      0

      ,

      2

      ]

      [0,2]

      [0,2]

    • (

      e

      r

      r

      o

      r

      ,

      n

      e

      t

      w

      o

      r

      k

      error, network

      error,network):在第

      2

      2

      2

      3

      3

      3

      4

      4

      4 条日志中同时出现,共现

      3

      3

      3

      输出

      [

      0

      ,

      3

      ]

      [0,3]

      [0,3]

    • (

      w

      a

      r

      n

      i

      n

      g

      ,

      n

      e

      t

      w

      o

      r

      k

      warning, network

      warning,network):在第

      2

      2

      2

      4

      4

      4 条日志中同时出现,共现

      2

      2

      2

      输出

      [

      2

      ,

      3

      ]

      [2,3]

      [2,3] 最终结果:统计次数

      [

      4

      ,

      2

      ,

      2

      ,

      2

      ]

      [4,2,2,2]

      [4,2,2,2] + 关联组合索引

      [

      0

      ,

      1

      ,

      0

      ,

      2

      ,

      0

      ,

      3

      ,

      2

      ,

      3

      ]

      [0,1,0,2,0,3,2,3]

      [0,1,0,2,0,3,2,3]

    样例3

    输入

    4 2
    Error in module A
    Module error B error
    Error module C error
    Module error D
    error
    module

    输出

    6,4,0,1

    说明 关键词统计:

    e

    r

    r

    o

    r

    error

    error 出现

    6

    6

    6 次(第

    1

    1

    1

    1

    1

    1 次,第

    2

    2

    2

    2

    2

    2 次,第

    3

    3

    3

    2

    2

    2 次,第

    4

    4

    4

    1

    1

    1 次),

    m

    o

    d

    u

    l

    e

    module

    module 出现

    4

    4

    4 次 关联组合:(

    e

    r

    r

    o

    r

    ,

    m

    o

    d

    u

    l

    e

    error, module

    error,module)在第

    1

    1

    1

    2

    2

    2

    3

    3

    3

    4

    4

    4 条日志中都同时出现,共现

    4

    4

    4

    输出

    [

    0

    ,

    1

    ]

    [0,1]

    [0,1] 最终结果:统计次数

    [

    6

    ,

    4

    ]

    [6,4]

    [6,4]

    +

    +

    + 关联组合索引

    [

    0

    ,

    1

    ]

    [0,1]

    [0,1]

    样例4

    输入

    3 5
    Test log one
    Test log two
    Test log three
    test
    log
    one
    two
    three

    输出

    3,3,1,1,1,0,1

    说明 关键词统计:

    t

    e

    s

    t

    test

    test 出现

    3

    3

    3 次,

    l

    o

    g

    log

    log 出现

    3

    3

    3 次,

    o

    n

    e

    one

    one 出现

    1

    1

    1 次,

    t

    w

    o

    two

    two 出现

    1

    1

    1 次,

    t

    h

    r

    e

    e

    three

    three 出现

    1

    1

    1 次 关联组合:(

    t

    e

    s

    t

    ,

    l

    o

    g

    test, log

    test,log)在第

    1

    1

    1

    2

    2

    2

    3

    3

    3 条日志中都同时出现,共现

    3

    3

    3

    输出

    [

    0

    ,

    1

    ]

    [0,1]

    [0,1] 其他关键词组合未达到

    2

    2

    2 次共现标准 最终结果:统计次数

    [

    3

    ,

    3

    ,

    1

    ,

    1

    ,

    1

    ]

    [3,3,1,1,1]

    [3,3,1,1,1]

    +

    +

    + 关联组合索引

    [

    0

    ,

    1

    ]

    [0,1]

    [0,1]题解

    题解

    思路:模拟

  • 按照题目给出的单词边界对每条日志进行分割提取出每条日志的单词。
  • 题目说明关键词匹配大小写不敏感,可统一转换为小写进行匹配。
  • 记录每个日志各个关键词出现数量,以及各关键字在每一个日志出现情况。
  • 通过枚举i, j和记录的关键词在每一个日志出现情况,找出经常关联关键词。
  • C++

    #include<bits/stdc++.h>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    using namespace std;

    string toLower(string s) {
    transform(s.begin(), s.end(), s.begin(),[](unsigned char c) {
    return tolower(c);
    });
    return s;
    }

    bool isDelim(char c) {
    return isspace(static_cast<unsigned char>(c)) || c == ',' || c == '.' ||
    c == '!' || c == '?' || c == ';' || c == ':';
    }

    // 对日志进行分词
    vector<string> tokenize(const string& log) {
    vector<string> words;
    string cur;
    for (char c : log) {
    if (isDelim(c)) {
    if (!cur.empty()) {
    words.push_back(toLower(cur));
    cur.clear();
    }
    } else {
    cur += c;
    }
    }
    if (!cur.empty()) words.push_back(toLower(cur));
    return words;
    }

    vector<int> totalKeyWord(vector<string>& logs, vector<string>& keywords) {
    int n = logs.size();
    int m = keywords.size();
    vector<int> keywordCount(m, 0);
    // 映射关键字(统一转换为小写)到索引
    map<string, int> keyWordIndex;

    for (int i = 0; i < keywords.size(); i++) {
    keyWordIndex[keywords[i]] = i;
    }
    vector<vector<bool>> isOccur(n, vector<bool>(m, false));
    for (int i = 0; i < n; i++) {
    vector<string> words = tokenize(logs[i]);
    for (auto& word : words) {
    // 统一转换小写
    string tmp = toLower(word);
    if (keyWordIndex.find(tmp) != keyWordIndex.end()) {
    int pos = keyWordIndex[tmp];
    keywordCount[pos]++;
    isOccur[i][pos] = true;
    }
    }
    }

    vector<int> ans;
    for (int i = 0; i < m; i++) {
    ans.push_back(keywordCount[i]);
    }

    // 找出经常关联
    for (int i = 0; i < m; i++) {
    for (int j = i + 1; j < m; j++) {
    // 同时出现次数
    int count = 0;
    for (int k = 0; k < n; k++) {
    if (!isOccur[k][i] || !isOccur[k][j]) {
    continue;
    }
    count++;
    if (count >= 2) {
    break;
    }
    }
    if (count >= 2) {
    ans.push_back(i);
    ans.push_back(j);
    }
    }
    }
    return ans;
    }

    int main() {
    int n, m;
    cin >> n >> m;
    vector<string> logs(n);
    vector<string> keywords(m);
    cin.ignore();
    for (int i = 0; i < n; i++) {
    getline(cin, logs[i]);
    }
    for (int i = 0; i < m; i++) {
    getline(cin, keywords[i]);
    }
    vector<int> ans = totalKeyWord(logs, keywords);
    // 输出结果
    for (int i = 0; i < ans.size(); i++) {
    if (i > 0) {
    cout << ",";
    }
    cout << ans[i];
    }
    return 0;
    }

    Java

    import java.io.*;
    import java.util.*;

    public class Main {

    static String toLower(String s) {
    return s.toLowerCase();
    }

    static boolean isDelim(char c) {
    return Character.isWhitespace(c)
    || c == ','
    || c == '.'
    || c == '!'
    || c == '?'
    || c == ';'
    || c == ':';
    }

    // 对日志进行分词
    static List<String> tokenize(String log) {
    List<String> words = new ArrayList<>();
    StringBuilder cur = new StringBuilder();

    for (char c : log.toCharArray()) {
    if (isDelim(c)) {
    if (cur.length() > 0) {
    words.add(toLower(cur.toString()));
    cur.setLength(0);
    }
    } else {
    cur.append(c);
    }
    }

    if (cur.length() > 0) {
    words.add(toLower(cur.toString()));
    }

    return words;
    }

    static List<Integer> totalKeyWord(List<String> logs, List<String> keywords) {
    int n = logs.size();
    int m = keywords.size();

    int[] keywordCount = new int[m];

    // 映射关键字(统一转换为小写)到索引
    Map<String, Integer> keyWordIndex = new HashMap<>();

    for (int i = 0; i < m; i++) {
    keyWordIndex.put(keywords.get(i), i);
    }

    boolean[][] isOccur = new boolean[n][m];

    for (int i = 0; i < n; i++) {
    List<String> words = tokenize(logs.get(i));

    for (String word : words) {
    String tmp = toLower(word);

    if (keyWordIndex.containsKey(tmp)) {
    int pos = keyWordIndex.get(tmp);
    keywordCount[pos]++;
    isOccur[i][pos] = true;
    }
    }
    }

    List<Integer> ans = new ArrayList<>();

    for (int x : keywordCount) {
    ans.add(x);
    }

    // 找出经常关联
    for (int i = 0; i < m; i++) {
    for (int j = i + 1; j < m; j++) {

    int count = 0;

    for (int k = 0; k < n; k++) {
    if (!isOccur[k][i] || !isOccur[k][j]) {
    continue;
    }

    count++;

    if (count >= 2) {
    break;
    }
    }

    if (count >= 2) {
    ans.add(i);
    ans.add(j);
    }
    }
    }

    return ans;
    }

    public static void main(String[] args) throws Exception {

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    String[] first = br.readLine().trim().split("\\\\s+");

    int n = Integer.parseInt(first[0]);
    int m = Integer.parseInt(first[1]);

    List<String> logs = new ArrayList<>();

    for (int i = 0; i < n; i++) {
    logs.add(br.readLine());
    }

    List<String> keywords = new ArrayList<>();

    for (int i = 0; i < m; i++) {
    keywords.add(br.readLine());
    }

    List<Integer> ans = totalKeyWord(logs, keywords);

    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < ans.size(); i++) {
    if (i > 0) {
    sb.append(",");
    }
    sb.append(ans.get(i));
    }

    System.out.print(sb);
    }
    }

    Python

    def to_lower(s):
    return s.lower()

    def is_delim(c):
    return c.isspace() or c in ",.!?;:"

    # 对日志进行分词
    def tokenize(log):
    words = []
    cur = []

    for c in log:
    if is_delim(c):
    if cur:
    words.append("".join(cur).lower())
    cur = []
    else:
    cur.append(c)

    if cur:
    words.append("".join(cur).lower())

    return words

    def total_key_word(logs, keywords):
    n = len(logs)
    m = len(keywords)

    keyword_count = [0] * m

    # 映射关键字(统一转换为小写)到索引
    keyword_index = {}

    for i, kw in enumerate(keywords):
    keyword_index[kw] = i

    is_occur = [[False] * m for _ in range(n)]

    for i in range(n):
    words = tokenize(logs[i])

    for word in words:
    tmp = word.lower()

    if tmp in keyword_index:
    pos = keyword_index[tmp]
    keyword_count[pos] += 1
    is_occur[i][pos] = True

    ans = keyword_count[:]

    # 找出经常关联
    for i in range(m):
    for j in range(i + 1, m):

    cnt = 0

    for k in range(n):
    if not is_occur[k][i] or not is_occur[k][j]:
    continue

    cnt += 1

    if cnt >= 2:
    break

    if cnt >= 2:
    ans.append(i)
    ans.append(j)

    return ans

    n, m = map(int, input().split())

    logs = [input() for _ in range(n)]
    keywords = [input() for _ in range(m)]

    ans = total_key_word(logs, keywords)

    print(",".join(map(str, ans)))

    JavaScript

    const readline = require("readline");

    function toLower(s) {
    return s.toLowerCase();
    }

    function isDelim(c) {
    return /\\s/.test(c) || ",.!?;:".includes(c);
    }

    // 对日志进行分词
    function tokenize(log) {
    const words = [];
    let cur = "";

    for (const c of log) {
    if (isDelim(c)) {
    if (cur.length > 0) {
    words.push(cur.toLowerCase());
    cur = "";
    }
    } else {
    cur += c;
    }
    }

    if (cur.length > 0) {
    words.push(cur.toLowerCase());
    }

    return words;
    }

    function totalKeyWord(logs, keywords) {
    const n = logs.length;
    const m = keywords.length;

    const keywordCount = Array(m).fill(0);

    // 映射关键字(统一转换为小写)到索引
    const keywordIndex = new Map();

    for (let i = 0; i < m; i++) {
    keywordIndex.set(keywords[i], i);
    }

    const isOccur = Array.from(
    { length: n },
    () => Array(m).fill(false)
    );

    for (let i = 0; i < n; i++) {
    const words = tokenize(logs[i]);

    for (const word of words) {
    const tmp = word.toLowerCase();

    if (keywordIndex.has(tmp)) {
    const pos = keywordIndex.get(tmp);
    keywordCount[pos]++;
    isOccur[i][pos] = true;
    }
    }
    }

    const ans = [keywordCount];

    // 找出经常关联
    for (let i = 0; i < m; i++) {
    for (let j = i + 1; j < m; j++) {

    let cnt = 0;

    for (let k = 0; k < n; k++) {
    if (!isOccur[k][i] || !isOccur[k][j]) {
    continue;
    }

    cnt++;

    if (cnt >= 2) {
    break;
    }
    }

    if (cnt >= 2) {
    ans.push(i);
    ans.push(j);
    }
    }
    }

    return ans;
    }

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

    const lines = [];

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

    rl.on("close", () => {
    let idx = 0;

    const [n, m] = lines[idx++].trim().split(/\\s+/).map(Number);

    const logs = [];

    for (let i = 0; i < n; i++) {
    logs.push(lines[idx++]);
    }

    const keywords = [];

    for (let i = 0; i < m; i++) {
    keywords.push(lines[idx++]);
    }

    const ans = totalKeyWord(logs, keywords);

    console.log(ans.join(","));
    });

    Go

    package main

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

    func toLower(s string) string {
    return strings.ToLower(s)
    }

    func isDelim(c byte) bool {
    return c == ' ' ||
    c == '\\t' ||
    c == '\\n' ||
    c == '\\r' ||
    c == ',' ||
    c == '.' ||
    c == '!' ||
    c == '?' ||
    c == ';' ||
    c == ':'
    }

    // 对日志进行分词
    func tokenize(log string) []string {
    words := make([]string, 0)
    cur := strings.Builder{}

    for i := 0; i < len(log); i++ {
    c := log[i]

    if isDelim(c) {
    if cur.Len() > 0 {
    words = append(words, strings.ToLower(cur.String()))
    cur.Reset()
    }
    } else {
    cur.WriteByte(c)
    }
    }

    if cur.Len() > 0 {
    words = append(words, strings.ToLower(cur.String()))
    }

    return words
    }

    func totalKeyWord(logs []string, keywords []string) []int {
    n := len(logs)
    m := len(keywords)

    keywordCount := make([]int, m)

    // 映射关键字(统一转换为小写)到索引
    keyWordIndex := make(map[string]int)

    for i := 0; i < m; i++ {
    keyWordIndex[keywords[i]] = i
    }

    isOccur := make([][]bool, n)

    for i := 0; i < n; i++ {
    isOccur[i] = make([]bool, m)
    }

    for i := 0; i < n; i++ {
    words := tokenize(logs[i])

    for _, word := range words {
    tmp := strings.ToLower(word)

    if pos, ok := keyWordIndex[tmp]; ok {
    keywordCount[pos]++
    isOccur[i][pos] = true
    }
    }
    }

    ans := make([]int, 0)

    ans = append(ans, keywordCount)

    // 找出经常关联
    for i := 0; i < m; i++ {
    for j := i + 1; j < m; j++ {

    cnt := 0

    for k := 0; k < n; k++ {
    if !isOccur[k][i] || !isOccur[k][j] {
    continue
    }

    cnt++

    if cnt >= 2 {
    break
    }
    }

    if cnt >= 2 {
    ans = append(ans, i, j)
    }
    }
    }

    return ans
    }

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

    var n, m int
    fmt.Fscan(reader, &n, &m)
    reader.ReadString('\\n')

    logs := make([]string, n)

    for i := 0; i < n; i++ {
    line, _ := reader.ReadString('\\n')
    logs[i] = strings.TrimRight(line, "n")
    }

    keywords := make([]string, m)

    for i := 0; i < m; i++ {
    line, _ := reader.ReadString('\\n')
    keywords[i] = strings.TrimRight(line, "\\n")
    }

    ans := totalKeyWord(logs, keywords)

    for i := 0; i < len(ans); i++ {
    if i > 0 {
    fmt.Print(",")
    }
    fmt.Print(ans[i])
    }
    }

    C语言

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

    #define MAX_LOGS 1000
    #define MAX_KEYWORDS 100
    #define MAX_LEN 1005

    void toLower(char *s) {
    for (int i = 0; s[i]; i++) {
    s[i] = tolower((unsigned char)s[i]);
    }
    }

    bool isDelim(char c) {
    return isspace((unsigned char)c)
    || c == ','
    || c == '.'
    || c == '!'
    || c == '?'
    || c == ';'
    || c == ':';
    }

    // 对日志进行分词
    int tokenize(char *log, char words[][MAX_LEN]) {
    int cnt = 0;
    char cur[MAX_LEN];
    int len = 0;

    for (int i = 0; log[i]; i++) {
    char c = log[i];

    if (isDelim(c)) {
    if (len > 0) {
    cur[len] = '\\0';
    toLower(cur);
    strcpy(words[cnt++], cur);
    len = 0;
    }
    } else {
    cur[len++] = c;
    }
    }

    if (len > 0) {
    cur[len] = '\\0';
    toLower(cur);
    strcpy(words[cnt++], cur);
    }

    return cnt;
    }

    int main() {

    int n, m;
    scanf("%d %d", &n, &m);
    getchar();

    char logs[MAX_LOGS][MAX_LEN];
    char keywords[MAX_KEYWORDS][MAX_LEN];

    for (int i = 0; i < n; i++) {
    fgets(logs[i], MAX_LEN, stdin);
    logs[i][strcspn(logs[i], "\\n")] = '\\0';
    }

    for (int i = 0; i < m; i++) {
    fgets(keywords[i], MAX_LEN, stdin);
    keywords[i][strcspn(keywords[i], "\\n")] = '\\0';
    }

    int keywordCount[MAX_KEYWORDS] = {0};
    bool isOccur[MAX_LOGS][MAX_KEYWORDS] = {false};

    for (int i = 0; i < n; i++) {

    char words[2000][MAX_LEN];

    int wordCnt = tokenize(logs[i], words);

    for (int j = 0; j < wordCnt; j++) {

    for (int k = 0; k < m; k++) {

    if (strcmp(words[j], keywords[k]) == 0) {
    keywordCount[k]++;
    isOccur[i][k] = true;
    }
    }
    }
    }

    bool first = true;

    for (int i = 0; i < m; i++) {
    if (!first) printf(",");
    first = false;
    printf("%d", keywordCount[i]);
    }

    // 找出经常关联
    for (int i = 0; i < m; i++) {
    for (int j = i + 1; j < m; j++) {

    int cnt = 0;

    for (int k = 0; k < n; k++) {

    if (!isOccur[k][i] || !isOccur[k][j]) {
    continue;
    }

    cnt++;

    if (cnt >= 2) {
    break;
    }
    }

    if (cnt >= 2) {
    printf(",%d,%d", i, j);
    }
    }
    }

    return 0;
    }

    赞(0)
    未经允许不得转载:171主机测评 » 华为OD机试真题 新系统【日志关键词统计】
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址