计算误码率

一、题目描述

误码率是最常用的数据通信传输质量指标。它可以理解为"在多少位数据中出现一位差错"。

移动通信网络中的误码率主要是指比特误码率,其计算公式如下: 比特误码率=错误比特数/传输总比特数,

为了简单,我们使用字符串来标识通信的信息,一个字符错误了,就认为出现了一个误码

输入一个标准的字符串,和一个传输后的字符串,计算误码率

字符串会被压缩,

例:"2A3B4D5X1Z"表示"AABBBDDDDXXXXXZ"

用例会保证两个输入字符串解压后长度一致,解压前的长度不一定一致

每个生成后的字符串长度<100000000。

二、输入输出描述

输入描述

  • 第一行:标准的字符串,每行字符串 (压缩后的) 长度<100000;
  • 第二行:传输后的字符串,每行字符串 (压缩后的) 长度<100000。

输出描述

  • 错误的字等数量/展开后的总长度

    备注

    注意:展开后的字符串不含数字

三、示例

|----|-----------|
| 输入 | 3A3B 2A4B |
| 输出 | 1/6 |
| 说明 | |

|----|-----------|
| 输入 | 5Y5Z 5Y5Z |
| 输出 | 0/10 |
| 说明 | |

|----|---------|
| 输入 | 4Y5Z 9Y |
| 输出 | 5/9 |
| 说明 | |

四、解题思路

  1. 核心思想

采用压缩字符串结构化解析 + 链表头部逐段对比 + 剩余长度复用 的策略,先将非结构化的压缩字符串转为可操作的ZipStr链表,再按顺序逐段对比字符和长度,统计差异与相同的可匹配长度,最终按指定格式输出结果。核心是结构化解析简化操作,逐段对比保证顺序一致性,剩余复用确保长度精准统计

  1. 问题本质分析
  • 表层问题:对两个压缩字符串进行对比,统计字符差异和相同的可匹配长度,按格式返回结果;
  • 深层问题:
  1. 格式解析问题:压缩字符串是 "数字 + 字符" 的混合格式,直接对比无法区分数字和字符,需先结构化解析为 "次数 + 字符" 的单元,简化后续操作;

  2. 顺序对比问题:压缩字符串的字符顺序是固定的(从左到右),需按原顺序逐段对比,不能打乱顺序,链表的头部操作可完美保证顺序一致性;

  3. 长度匹配问题:两段字符的重复次数可能不一致,需取最小值作为可匹配长度,同时保留剩余长度继续参与对比,避免长度统计遗漏;

  4. 统计逻辑问题:需严格区分 "字符相同" 和 "字符不同" 的可匹配长度,分别累加后按固定格式拼接结果。

  5. 核心逻辑

  • 结构化解析:将压缩字符串解析为LinkedList<ZipStr>,把 "数字 + 字符" 的混合字符串转为结构化单元,每个单元包含明确的重复次数和对应字符,为后续对比提供清晰的数据结构;
  • 逐段顺序对比:以链表头部移除的方式,按压缩字符串的原始顺序逐段取出ZipStr单元,保证对比顺序与字符串原始顺序一致;
  • 可匹配长度计算:对每一对ZipStr单元,取重复次数的最小值作为可匹配长度,确保统计的是两段字符能相互匹配的最大长度;
  • 差异与相同统计:根据字符是否一致,将可匹配长度分别累加到diff(差异)或same(相同);
  • 剩余长度复用:对超出可匹配长度的ZipStr单元,更新剩余次数后放回原链表头部,继续参与下一轮对比,确保所有可匹配长度都被统计;
  • 结果拼接:按diff/(diff+same)的格式拼接统计结果,返回最终字符串。
  1. 步骤拆解

  2. 压缩字符串结构化解析

    • 对每个输入的压缩字符串,调用getZipStrLink方法;
    • 遍历字符串,拼接数字字符为完整数字,遇到非数字字符时,创建ZipStr单元(数字转为重复次数,非数字为对应字符),加入LinkedList
    • 最终得到两个结构化的ZipStr链表(link1link2)。
  3. 初始化统计变量

    • 初始化diff=0(字符不同的可匹配长度总和)、same=0(字符相同的可匹配长度总和)。
  4. 链表头部逐段对比与统计

    • 进入循环(终止条件:link1为空):
    1. 分别从link1link2头部移除并获取ZipStr单元(zipStr1zipStr2);
    2. 计算可匹配长度:compareCount = Math.min(zipStr1.num, zipStr2.num)
    3. 字符对比:若zipStr1.c != zipStr2.cdiff += compareCount;否则same += compareCount
    4. 剩余长度处理:
      • zipStr1.num > compareCount:更新zipStr1.num -= compareCount,放回link1头部,跳过后续zipStr2处理;
      • zipStr2.num > compareCount:更新zipStr2.num -= compareCount,放回link2头部;
  5. 结果拼接与返回

    • 计算总可匹配长度:total = diff + same
    • diff/total的格式拼接字符串,返回该结果。

五、代码实现

java 复制代码
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
  static class ZipStr {
    int num;
    char c;

    public ZipStr(int num, char c) {
      this.num = num;
      this.c = c;
    }
  }

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

    String s1 = sc.nextLine();
    String s2 = sc.nextLine();

    System.out.println(getResult(s1, s2));
  }

  public static String getResult(String s1, String s2) {
    LinkedList<ZipStr> link1 = getZipStrLink(s1);
    LinkedList<ZipStr> link2 = getZipStrLink(s2);

    int diff = 0;
    int same = 0;

    while (link1.size() > 0) {
      ZipStr zipStr1 = link1.removeFirst();
      ZipStr zipStr2 = link2.removeFirst();

      int compareCount = Math.min(zipStr1.num, zipStr2.num);

      if (zipStr1.c != zipStr2.c) {
        diff += compareCount;
      } else {
        same += compareCount;
      }

      if (zipStr1.num > compareCount) {
        zipStr1.num -= compareCount;
        link1.addFirst(zipStr1);
        continue;
      }

      if (zipStr2.num > compareCount) {
        zipStr2.num -= compareCount;
        link2.addFirst(zipStr2);
      }
    }

    return diff + "/" + (diff + same);
  }

  public static LinkedList<ZipStr> getZipStrLink(String s) {
    LinkedList<ZipStr> link = new LinkedList<>();

    StringBuilder num = new StringBuilder();

    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);

      if (c >= '0' && c <= '9') {
        num.append(c);
      } else {
        link.add(new ZipStr(Integer.parseInt(num.toString()), c));
        num = new StringBuilder();
      }
    }

    return link;
  }
}
相关推荐
二哈赛车手1 天前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
吃好睡好便好1 天前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
栗子~~1 天前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
YDS8291 天前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
仰泳之鹅1 天前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
nashane1 天前
HarmonyOS 6学习:CapsLock键失效诊断与长截图完整实现指南
学习·华为·harmonyos
发现一只大呆瓜1 天前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
未若君雅裁1 天前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
AI人工智能+电脑小能手1 天前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记1 天前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring