专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
给定一个字符串的摘要算法,请输出给定字符串的摘要值:
- 去除字符串中非字母的符号;
- 如果出现连续字符(不区分大小写),则输出该字符(小写)+连续出现的次数;
- 如果时非连续的字符(不区分大小写),则输出该字符(小写)+该字母之后字符串中出现该字符的次数;
- 对按照以上方式表示后的字符串进行排序,字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前;
二、输入描述
一行字符串。
三、输出描述
摘要字符串。
四、解题思路
1、核心思路:
- 如果当前字母和上一个字母相同,该字母连续次数记为+1;
- 如果当前字母和上一个字母不同;
- 如果当前字符的连续次数大于1,表示是连续字符,输出即可;
- 如果只有1个,则要获取后面字符串中该字符的个数;
- 字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前;
2、具体思路如下:
- 输入一行字符串,不区分大小写;
- 定义一个数组chCountArr,记录字母出现的次数;
- 定义一个字符串,存储字符串中的字母;
- 定义一个集合,记录统计连续字符和非连续字符的字符和个数;
- 遍历输入的字符串;
- 如果当前字母和上一个字母相同,该字母连续次数记为+1;
- 如果当前字母和上一个字母不同;
- 如果当前字符的连续次数大于1,表示是连续字符,输出即可;
- 如果只有1个,则要获取后面字符串中该字符的个数;
- 更新current连续次数为1;
- 字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前;
- 输出摘要字符串;
五、Java算法源码
package com.guor.od;
import java.util.Scanner;
import java.util.*;
public class OdTest03 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 不区分大小写
String line = sc.nextLine().toLowerCase();
// 字母出现的次数
int[] chCountArr = new int[128];
// 字符串中的字母
StringBuilder builder = new StringBuilder();
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c >= 'a' && c <= 'z') {
chCountArr[c]++;
builder.append(c);
}
}
line = builder.toString();
// 统计连续字符和非连续字符的字符和个数
List<MyCharBean> charList = new ArrayList<MyCharBean>();
// 该字母连续次数记为1
int continuousCount = 1;
// 遍历输入的字符串
for (int i = 0; i < line.length(); i++) {
// 当前字母
char current = line.charAt(i);
// 下一个字符
char next = ' ';
// 如果不是最后一个字符
if (i + 1 != line.length()) {
next = line.charAt(i + 1);
}
// 后面字符串中该字母的连续个数
chCountArr[current]--;
// 如果当前字母和上一个字母相同,该字母连续次数记为+1
if (current == next) {
continuousCount++;
// 如果当前字母和上一个字母不同
} else {
// 如果当前字符的连续次数大于1,表示是连续字符,输出即可
// 如果只有1个,则要获取后面字符串中该字符的个数
int num = continuousCount > 1 ? continuousCount : chCountArr[current];
charList.add(new MyCharBean(current, num));
// 更新current连续次数为1
continuousCount = 1;
}
}
// 字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前
charList.sort((x, y) -> x.num != y.num ? y.num - x.num : x.ch - y.ch);
StringBuilder sb = new StringBuilder();
for (MyCharBean c : charList) {
sb.append(c.toString());
}
System.out.println(sb);
}
/**
* 字母出现的次数
*/
static class MyCharBean {
// 字母
char ch;
// 字母出现的次数
int num;
public MyCharBean(char ch, int num) {
this.ch = ch;
this.num = num;
}
/**
* 按指定格式输出
*/
@Override
public String toString() {
return this.ch + "" + this.num;
}
}
}
六、效果展示
1、输入
abcccbbaa
2、输出
c3a2a2b2b2
3、说明
abcccbbaa
- 第1个字符a,不连续,获取后面字符串中a的个数2 – a2;
- 第2个字符b,不连续,获取后面字符串中b的个数2 – b2;
- 第3个字符c,连续,一共3个 --c3;
- 第6个字符b,连续,一共2个 --b2;
- 第8个字符a,连续,一共2个 --a2;
- 变为a2b2c3b2a2;
输出c3a2a2b2b2
。
4、再输入
abcccbbabaaccbca
5、输出
a4b4a3c3a2b2c2b1a0b0c0
6、说明
- 第一个字符a,不连续,后面字符串中a的个数为4,输出a4;
- 第二个字符b,不连续,后面字符串中b的个数为4,输出b4;
- 第三个字符c,连续3个,输出c3;
- 第6个字符b,连续2个,输出b2;
- 第8个字符a,不连续,后面字符串中a的个数为3,输出a3;
- 第9个字符b,不连续,后面字符串中b的个数为1,输出b1;
- 第10个字符a,连续2个,输出a2;
- 第12个字符c,连续2个,输出c2;
- 第14个字符b,不连续,后面没有b,输出b0;
- 第15个字符c,不连续,后面没有c,输出c0;
- 第16个字符a,不连续,后面没有a,输出a0;
a4b4c3b2a3b1a2c2b0c0a0
a4b4a3c3a2b2c2b1a0b0c0
这么复杂?其实思路很简单,不信,你亲自来验证一下?
🏆下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。