文本统计分析 - 华为OD统一考试(C卷)

news/2024/7/20 16:19:41 标签: 华为od, 算法, java, c++, python, 数据结构, 机试

OD统一考试(C卷)

分值: 200分

题解: Java / Python / C++

alt

题目描述

有一个文件, 包含以一定规则写作的文本, 请统计文件中包含的文本数量

规则如下

  1. 文本以";“分隔,最后一条可以没有”;",但空文本不能算语句,比如"COMMAND A; ;"只能算一条语句.
    注意, 无字符/空白字符/制表符都算作"空"文本
  2. 文本可以跨行, 比如下面, 是一条文本, 而不是三条
    COMMAND A
    AND
    COMMAND B;
  3. 文本支持字符串, 字符串为成对的单引号(')或者成对的双引号(“), 字符串可能出现用转义字符(\)处理的单双引号(比如"your input is: \”")和转义字符本身, 比如
    COMMAND A “Say \“hello\””;
  4. 支持注释, 可以出现在字符串之外的任意位置, 注释以"–“开头, 到换行结束, 比如
    COMMAND A; – this is comment
    COMMAND – comment
    A AND COMMAND B;
    注意, 字符串内的”–", 不是注释

输入描述

文本文件

输出描述

包含的文本数量

示例1

输入:
COMMAND TABLE IF EXISTS "UNITED STATE";
COMMAND A GREAT (
    ID ADSAB,
    download_length INTE-GER,  -- test
    file_name TEXT,
    guid TEXT,
    mime_type TEXT,
    notifica-tionid INTEGER,
    original_file_name TEXT,
    pause_reason_type INTEGER,
    resumable_flag INTEGER,
    start_time INTEGER,
    state INTEGER,
    folder TEXT,
    path TEXT,
    total_length INTE-GER,
    url TEXT
);

输出:
2

题解

这个问题可以通过使用有限状态机(Finite State Machine, FSM)来解决。

我们可以定义四种状态:正常文本、双引号字符串、单引号字符串和注释内容。

然后,我们遍历输入的每一行,根据当前字符和状态来决定下一个状态以及是否需要增加文本计数。

Java

java">/**
 * @author code5bug
 */
public class Main {
    enum State {  // 表示四种状态:双引号字符串,单引号字符串,注释内容, 正常文本
        DoubleStr, SingleStr, Comment, Normal
    }

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

        // 前一个字符, 这次初始化为 ';' 是为了避免第一个字符就是 ';' 导致文本计机数不准
        char pre = ';';
        State state = State.Normal;

        int result = 0;
        while (in.hasNext()) {
            char[] cs = in.nextLine().toCharArray();
            for (char c : cs) {
                if (Character.isWhitespace(c)) continue;  // 空白符

                if (state == State.Normal) {
                    if (pre == '-' && c == '-') {  // 注释内容
                        state = State.Comment;
                    } else if (c == '\"') {  // 双引号开始的字符串
                        state = State.DoubleStr;
                    } else if (c == '\'') {  // 单引号开始的字符串
                        state = State.SingleStr;
                    } else if (c == ';') { // 遇到分割符
                        // 不是相邻的 ';' 则 + 1
                        if (pre != ';') result++;
                    }
                } else if (state == State.DoubleStr && c == '\"') { // 字符串双引号结束
                    state = State.Normal;
                } else if (state == State.SingleStr && c == '\'') { // 字符串单引号结束
                    state = State.Normal;
                }

                pre = c;
            }

            if (state == State.Comment) {  // 注释只到行结尾
                state = State.Normal;
            }
        }

        if (pre != ';') result++;  // 结尾的 ;

        System.out.println(result);
    }
}

Python

python">import sys

# 表示四种状态:双引号字符串,单引号字符串,注释内容, 正常文本
DoubleStr, SingleStr, Comment, Normal = 1, 2, 3, 4

text_cnt = 0  # 文本计数器
state = Normal  # 初始状态为正常文本
pre = ';'  # 前一个字符, 这次初始化为 ';' 是为了避免第一个字符就是 ';' 导致文本计机数不准

for line in sys.stdin:
    for c in line:
        #  如果 c 为空字符\制表符
        if c.isspace():
            continue

        if state == Normal:
            if c == '"':  # 开始双引号字符串
                state = DoubleStr
            elif c == "'":  # 开始单引号字符串
                state = SingleStr
            elif c == '-' and pre == '-':  # 开始注释内容
                state = Comment
            elif c == ';' and pre != ';':  # 遇到; 分割
                text_cnt += 1
        elif state == DoubleStr and c == '"':  # 双引号字符串结束
            state = Normal
        elif state == SingleStr and c == "'":  # 单引号字符串结束
            state = Normal

        pre = c

    # 注释只到行结尾
    if state == Comment:
        state = Normal

# 结尾的 ; 分割
if pre != ';':
    text_cnt += 1

print(text_cnt)

C++

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

enum class State
{
    // 双引号字符串, 单引号字符串, 注释, 正常文本
    double_str,
    single_str,
    comment,
    normal
};

int main()
{
    int    text_cnt = 0;   // 文本数量
    string line;

    State state = State::normal;

    // 前一个字符, 这次初始化为 ';' 是为了避免第一个字符就是 ';' 导致文本计机数不准
    char pre = ';';
    while (getline(cin, line)) {
        for (char c : line) {
            // 空字符
            if (isspace(c)) continue;

            if (state == State::normal) {
                if (c == '"') {   // 开始双引号字符串
                    state = State::double_str;
                } else if (c == '\'') {   // 开始单引号字符串
                    state = State::single_str;
                } else if (c == '-' && pre == '-') {   // 开始注释内容
                    state = State::comment;
                } else if (c == ';' && pre != ';') {   // 遇到; 分割
                    text_cnt++;
                }
            } else if (state == State::double_str && c == '"') {   // 双引号字符串结束
                state = State::normal;
            } else if (state == State::single_str && c == '\'') {   // 单引号字符串结束
                state = State::normal;
            }

            pre = c;
        }

        if (state == State::comment) {
            state = State::normal;
        }
    }

    // 结尾的 ;
    if (pre != ';') text_cnt++;

    cout << text_cnt << endl;

    return 0;
}

‍❤️‍华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏


http://www.niftyadmin.cn/n/5414703.html

相关文章

[数据集][实例分割]小麦病害分割数据集899张12类别

数据集格式&#xff1a;labelmeyolo格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件以及对应yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;899 标注数量(json文件个数)&#xff1a;899 标注数量(txt文件个数)&#xff1a;899 标注类别数&#xff1a;12…

【Qt】四种绘图设备详细使用

绘图设备有4个: **绘图设备是指继承QPainterDevice的子类————**QPixmap QImage QPicture QBitmap(黑白图片) QBitmap——父类QPixmapQPixmap图片类&#xff0c;主要用来显示&#xff0c;它针对于显示器显示做了特殊优化&#xff0c;依赖于平台的&#xff0c;只能在主线程…

Leetcode : 面试题 10.01. 合并排序的数组

思路&#xff1a;设定两个指针ptrA和ptrB&#xff0c;遍历两个数组比较&#xff0c;对A数组进行修改&#xff1b; A.insert添加&#xff0c;最后进行A.erase删除多余元素&#xff0c;提醒&#xff0c;数组长度提前记录一下&#xff0c;方便后续删除 #include <iostream>…

想开发苹果群控软件?先了解这些代码!

随着智能设备的普及&#xff0c;群控软件的需求日益增加&#xff0c;特别是针对苹果设备的群控软件&#xff0c;因其出色的性能和广泛的用户基础&#xff0c;受到了开发者们的青睐。 然而&#xff0c;开发一款功能强大的苹果群控软件并非易事&#xff0c;需要深入了解苹果的开…

“你真的了解 JavaScript 类型检测吗?深入探讨 typeof、instanceof“

前言 在JavaScript的世界里&#xff0c;了解变量的类型是编程中的基本需求。JavaScript提供了两个操作符&#xff1a;typeof和instanceof&#xff0c;用于类型检测&#xff0c;但它们各有特点和适用场景。让我们通过一篇文章来深入探讨这两个操作符的用法和它们之间的区别。 …

Autosar教程-Mcal教程-GPT配置教程

3.3GPT配置、生成 3.3.1 GPT配置所需要的元素 GPT实际上就是硬件定时器,需要配置的元素有: 1)定时器时钟:定时器要工作需要使能它的时钟源 2)定时器分步:时钟源进到定时器后可以通过分频后再给到定时器 定时器模块选择:MCU有多个定时器模块,需要决定使用哪个定时器模块作…

测试常用的Linux命令

前言 直接操作硬件 将把操作硬件的代码封装成系统调用&#xff0c;供程序员使用 虚拟机软件 可以模拟的具有完整硬件系统的功能 可以在虚拟机上安装不同的操作系统 Linux内核只有一个&#xff0c;发行版有很多种 内核来运行程序和管理像磁盘和打印机等硬件设备的核心程序 终端…

HarmonyOS NEXT应用开发案例——阻塞事件冒泡

介绍 本示例主要介绍在点击事件中&#xff0c;子组件enabled属性设置为false的时候&#xff0c;如何解决点击子组件模块区域会触发父组件的点击事件问题&#xff1b;以及触摸事件中当子组件触发触摸事件的时候&#xff0c;父组件如果设置触摸事件的话&#xff0c;如何解决父组…