📫 个人主页:深夜coding算法
📣 专栏系列:2026年华为最新OD机试题库详解
🔥 一次订阅,永久解锁 | 持续更新100+篇 | 6语言全覆盖
文章目录
- ❄️前言:
- ☀️一:题目描述
- 🌙 题目名称
- 🌙 题目内容
- 🌙 输入描述
- 🌙 输出描述
- 🌙 示例
- ☀️二:解题思路
- ☀️三:代码实现
- C++
- Java
- Python3
- C语言
- JavaScript
- Go
- ☀️四:复杂度分析
- ⭐ 五:易错点
- 坑1:ASCII码排序规则
- 坑2:不要漏掉数字
- 🌻共勉:
❄️前言:
统计频率 + 自定义排序,OD机试最爱考的组合。先数数,再排序,再加点花样。两步分开做,别混在一起。
☀️一:题目描述
🌙 题目名称
字符统计及重排
🌙 题目内容
给定一个字符串,包含字母和数字。请统计每个字符出现的次数,并按要求重新排列输出:
- 按照出现次数由大到小排序;
- 出现次数相同时:
- 如果是字母,按ASCII码从小到大排列;
- 如果是数字,按ASCII码从小到大排列;
- 如果次数相同且都是字母或都是数字,统一按 ASCII 从小到大排列。
🌙 输入描述
输入一个字符串S,长度不超过 1000。
🌙 输出描述
按规则输出重新排列后的字符串(每个字符后跟出现次数)。
🌙 示例
输入: xyxyXX 输出: x:2;y:2;X:2;说明:x出现2次,y出现2次,X出现2次。次数相同,按ASCII排序(X=88, x=120, y=121)。
☀️二:解题思路
两步走:
- 统计:用哈希表(或 int[128] 数组)记录每个字符的出现次数
- 排序:自定义比较器,次数降序→ASCII升序
☀️三:代码实现
C++
#include<iostream>#include<string>#include<vector>#include<algorithm>usingnamespacestd;intmain(){string s;cin>>s;intcnt[128]={0};for(charc:s)cnt[c]++;vector<pair<char,int>>v;for(inti=0;i<128;i++)if(cnt[i]>0)v.push_back({(char)i,cnt[i]});sort(v.begin(),v.end(),[](auto&a,auto&b){if(a.second!=b.second)returna.second>b.second;// 次数降序returna.first<b.first;// ASCII升序});for(auto&p:v)cout<<p.first<<":"<<p.second<<";";cout<<endl;}Java
importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);Strings=sc.nextLine();int[]cnt=newint[128];for(charc:s.toCharArray())cnt[c]++;List<int[]>list=newArrayList<>();for(inti=0;i<128;i++)if(cnt[i]>0)list.add(newint[]{i,cnt[i]});list.sort((a,b)->b[1]!=a[1]?b[1]-a[1]:a[0]-b[0]);for(int[]p:list)System.out.print((char)p[0]+":"+p[1]+";");System.out.println();}}Python3
s=input().strip()cnt={}forcins:cnt[c]=cnt.get(c,0)+1items=sorted(cnt.items(),key=lambdax:(-x[1],x[0]))forch,ninitems:print(f"{ch}:{n};",end="")print()C语言
#include<stdio.h>#include<string.h>#include<stdlib.h>typedefstruct{charch;intcnt;}Item;intcmp(constvoid*a,constvoid*b){Item*x=(Item*)a,*y=(Item*)b;if(x->cnt!=y->cnt)returny->cnt-x->cnt;returnx->ch-y->ch;}intmain(){chars[1024];scanf("%s",s);intcnt[128]={0};for(char*p=s;*p;p++)cnt[(int)*p]++;Item items[128];intn=0;for(inti=0;i<128;i++)if(cnt[i]>0){items[n].ch=i;items[n].cnt=cnt[i];n++;}qsort(items,n,sizeof(Item),cmp);for(inti=0;i<n;i++)printf("%c:%d;",items[i].ch,items[i].cnt);printf("\n");}JavaScript
consts=require('fs').readFileSync(0,'utf-8').trim();constcnt={};for(constcofs)cnt[c]=(cnt[c]||0)+1;constitems=Object.entries(cnt).sort(([a,ca],[b,cb])=>cb-ca||a.localeCompare(b));console.log(items.map(([ch,n])=>`${ch}:${n};`).join(''));Go
packagemainimport("fmt";"sort")funcmain(){varsstringfmt.Scan(&s)cnt:=make(map[rune]int)for_,c:=ranges{cnt[c]++}typeitemstruct{chrune;nint}items:=[]item{}forch,n:=rangecnt{items=append(items,item{ch,n})}sort.Slice(items,func(i,jint)bool{ifitems[i].n!=items[j].n{returnitems[i].n>items[j].n}returnitems[i].ch<items[j].ch})for_,it:=rangeitems{fmt.Printf("%c:%d;",it.ch,it.n)}fmt.Println()}☀️四:复杂度分析
| 指标 | 数值 |
|---|---|
| 时间复杂度 | O(N + KlogK),K为字符种类数(≤128) |
| 空间复杂度 | O(K) |
⭐ 五:易错点
坑1:ASCII码排序规则
次数相同按ASCII从小到大。注意大小写字母 ASCII 不同:大写字母(65-90)排在小写字母(97-122)前面。
坑2:不要漏掉数字
输入可能含数字字符,和字母一样统计,排在字母前面(数字ASCII 48-57)。
🌻共勉:
哈希统计 + 自定义排序,OD机试最经典的组合拳。练熟这道,类似的题都能套。
📫关于本专栏:一次订阅,永久解锁全部100+篇真题详解
🔥6语言全覆盖:Java | Python3 | C++ | C语言 | JsNode | Go