7.12真题华为OD机试真题 新系统 - 字符串压缩编码 (Java/Py/C/C++/Js/Go)
字符串压缩编码
2026 华为OD机试真题 7月12日华为OD上机新系统考试真题 100 分题型
点击查看华为 OD 机试真题完整目录:2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解
题目描述
给定一个只包含大小写英文字母的字符串,请实现字符串压缩编码功能。
压缩规则:
- 如果字符连续出现次数大于
1,则用字符加上出现次数表示 - 如果字符连续出现次数等于
1,则直接输出字符
输入描述
- 输入一行,包含一个字符串 str(长度 1≤∣str∣≤1000)
- 字符串只包含大小写英文字母
输出描述
输出压缩后的字符串
示例1
输入
aabcccccaaa输出
a2bc5a3说明
aa→a2b→b(单个字符不写数字)ccccc→c5aaa→a3
示例2
输入
b输出
b说明
- 单个字符直接输出
示例3
输入
AAbB输出
A2bB说明
AA→A2b→bB→B
示例4
输入
aaabbbcccaaa输出
a3b3c3a3说明
aaa→a3bbb→b3ccc→c3aaa→a3
解题思路
核心思想
字符串压缩编码采用双指针扫描的方式:使用一个慢指针i指向当前连续段的起点,一个快指针j向后扫描直到字符不同,从而统计连续相同字符的个数。
算法步骤
- 边界处理:若字符串为空,直接返回空串。
- 双指针扫描:
i指向当前连续段的起点,j向右移动直到s[j]与s[i]不同或到达末尾。 - 统计计数:
cnt = j - i即为当前字符的连续出现次数。 - 构建结果:
- 若
cnt > 1,拼接字符 + 数字。 - 若
cnt == 1,只拼接字符。
- 若
- 移动指针:
i = j,继续处理下一段。 - 返回结果:将所有片段拼接为最终字符串。
复杂度分析
- 时间复杂度:O(n),其中 n 为字符串长度,每个字符最多被访问两次。
- 空间复杂度:O(n),用于存储结果字符串。
Java
importjava.util.Scanner;publicclassMain{publicstaticStringcompress(Strings){intn=s.length();if(n==0)return"";StringBuilderres=newStringBuilder();inti=0;// 双指针:i 为当前段起点,j 向后扩张直到字符改变while(i<n){intj=i;while(j<n&&s.charAt(j)==s.charAt(i)){j++;}intcnt=j-i;// 计数 >1 才写数字,单个字符只写字母if(cnt>1){res.append(s.charAt(i)).append(cnt);}else{res.append(s.charAt(i));}i=j;// 跳到下一段起点}returnres.toString();}publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);Strings=sc.nextLine();System.out.println(compress(s));}}Python
defcompress(s:str)->str:n=len(s)ifn==0:return""res=[]i=0# 双指针:i 为当前段起点,j 向后扩张直到字符改变whilei<n:j=iwhilej<nands[j]==s[i]:j+=1cnt=j-i# 计数 >1 才写数字,单个字符只写字母ifcnt>1:res.append(f"{s[i]}{cnt}")else:res.append(s[i])i=j# 跳到下一段起点return"".join(res)if__name__=="__main__":importsys s=sys.stdin.read().strip()print(compress(s))JavaScript
// 使用 readline 读取输入constreadline=require('readline');functioncompress(s){constn=s.length;if(n===0)return"";letres="";leti=0;// 双指针:i 为当前段起点,j 向后扩张直到字符改变while(i<n){letj=i;while(j<n&&s[j]===s[i]){j++;}constcnt=j-i;// 计数 >1 才写数字,单个字符只写字母if(cnt>1){res+=s[i]+cnt;}else{res+=s[i];}i=j;// 跳到下一段起点}returnres;}constrl=readline.createInterface({input:process.stdin});letinput="";rl.on('line',line=>{input+=line;});rl.on('close',()=>{console.log(compress(input));});C++
#include<iostream>#include<string>usingnamespacestd;stringcompress(string s){intn=s.length();if(n==0)return"";string res="";inti=0;// 双指针:i 为当前段起点,j 向后扩张直到字符改变while(i<n){intj=i;while(j<n&&s[j]==s[i]){j++;}intcnt=j-i;// 计数 >1 才写数字,单个字符只写字母if(cnt>1){res+=s[i]+to_string(cnt);}else{res+=s[i];}i=j;// 跳到下一段起点}returnres;}intmain(){string s;cin>>s;cout<<compress(s);return0;}Go
packagemainimport("bufio""fmt""os""strconv""strings")// compress 双指针扫描字符串进行压缩编码funccompress(sstring)string{n:=len(s)ifn==0{return""}varres strings.Builder i:=0// 双指针:i 为当前段起点,j 向后扩张直到字符改变fori<n{j:=iforj<n&&s[j]==s[i]{j++}cnt:=j-i// 计数 >1 才写数字,单个字符只写字母ifcnt>1{res.WriteByte(s[i])res.WriteString(strconv.Itoa(cnt))}else{res.WriteByte(s[i])}i=j// 跳到下一段起点}returnres.String()}funcmain(){reader:=bufio.NewReader(os.Stdin)s,_:=reader.ReadString('\n')s=strings.TrimRight(s,"\r\n")fmt.Println(compress(s))}C语言
#include<stdio.h>#include<string.h>// compress 双指针扫描字符串进行压缩编码voidcompress(constchar*s,char*res){intn=strlen(s);if(n==0){res[0]='\0';return;}intidx=0;// res 的写入位置inti=0;// 双指针:i 为当前段起点,j 向后扩张直到字符改变while(i<n){intj=i;while(j<n&&s[j]==s[i]){j++;}intcnt=j-i;// 计数 >1 才写数字,单个字符只写字母if(cnt>1){res[idx++]=s[i];// 将数字转换为字符串charbuf[12];sprintf(buf,"%d",cnt);for(intk=0;buf[k]!='\0';k++){res[idx++]=buf[k];}}else{res[idx++]=s[i];}i=j;// 跳到下一段起点}res[idx]='\0';}intmain(){chars[1001];scanf("%s",s);charres[2001];compress(s,res);printf("%s\n",res);return0;}完整用例
用例1
输入
aabcccccaaa用例2
输入
b用例3
输入
AAbB用例4
输入
aaabbbcccaaa用例5
输入
abcdefg用例6
输入
aaaaaaaaaa用例7
输入
abababab用例8
输入
aAaAaA用例9
输入
zzzz...z(1000个z)用例10
输入
aaabbCCdddEEff文章目录
- 字符串压缩编码
- 题目描述
- 输入描述
- 输出描述
- 示例1
- 示例2
- 示例3
- 示例4
- 解题思路
- 核心思想
- 算法步骤
- 复杂度分析
- Java
- Python
- JavaScript
- C++
- Go
- C语言
- 完整用例
- 用例1
- 用例2
- 用例3
- 用例4
- 用例5
- 用例6
- 用例7
- 用例8
- 用例9
- 用例10
