#P3016. 字符串摘要(100分)
-
1000ms
Tried: 182
Accepted: 60
Difficulty: 5
所属公司 :
华为od
-
算法标签>模拟
字符串摘要(100分)
题面描述
给定一个字符串的摘要算法,请输出给定字符串的摘要值。
-
去除字符串中非字母的符号。
-
处理字符:
- 如果出现连续字符(不区分大小写),则输出:该字符(小写) + 连续出现的次数。
- 如果是非连续的字符(不区分大小写),则输出:该字符(小写) + 该字母之后字符串中出现的该字符的次数。
-
排序规则:
- 按照字母和紧随的数字作为一组进行排序。
- 数字大的在前,数字相同的,则按字母进行排序,字母小的在前。
思路
由于数据范围很小我们直接暴力也是可以做的,遇到非连续字符时直接扫一遍后面的即可
具体步骤
-
预处理:
- 首先遍历输入字符串,去除所有非字母字符,并将所有字母转换为小写,得到一个干净的字符串。
-
摘要生成:
- 遍历处理后的字符串,识别连续和非连续字符。
- 对于连续字符,统计连续出现的次数,并记录该字符及其次数。
- 对于非连续字符,统计该字符之后字符串中出现的次数,并记录该字符及其次数。
-
排序:
- 将记录的字符和次数存储为一个结构体或对象。
- 按照次数从大到小排序,如果次数相同,则按字母从小到大排序。
-
输出:
- 将排序后的字符和次数拼接成最终的摘要字符串。
cpp
#include <bits/stdc++.h>
using namespace std;
// 定义一个结构体存储字符及其次数
struct CharCount {
char ch;
int count;
};
// 自定义排序规则
bool compare(const CharCount &a, const CharCount &b) {
if(a.count != b.count)
return a.count > b.count; // 数字大的在前
return a.ch < b.ch; // 字母小的在前
}
int main(){
string s;
getline(cin, s);
// 去除非字母字符并转换为小写
string clean;
for(char c: s){
if(isalpha(c)){
clean += tolower(c);
}
}
vector<CharCount> result;
int n = clean.size();
int i = 0;
while(i < n){
char current = clean[i];
int count = 1;
int j = i + 1;
// 统计连续字符
while(j < n && clean[j] == current){
count++;
j++;
}
if(count > 1){
result.push_back(CharCount{current, count});
i = j;
}
else{
// 非连续字符,统计后续出现次数
int cnt = 0;
for(int k = i + 1; k < n; k++){
if(clean[k] == current){
cnt++;
}
}
result.push_back(CharCount{current, cnt});
i++;
}
}
// 排序
sort(result.begin(), result.end(), compare);
// 构建输出字符串
string output = "";
for(auto &item: result){
output += string(1, item.ch) + to_string(item.count);
}
cout << output;
}
python
# 定义一个类存储字符及其次数
class CharCount:
def __init__(self, ch, count):
self.ch = ch
self.count = count
# 自定义排序函数
def compare(a):
return (-a.count, a.ch)
def main():
s = input()
# 去除非字母字符并转换为小写
clean = ''.join([c.lower() for c in s if c.isalpha()])
result = []
n = len(clean)
i = 0
while i < n:
current = clean[i]
count = 1
j = i + 1
# 统计连续字符
while j < n and clean[j] == current:
count +=1
j +=1
if count >1:
result.append(CharCount(current, count))
i = j
else:
# 非连续字符,统计后续出现次数
cnt = clean[i+1:].count(current)
result.append(CharCount(current, cnt))
i +=1
# 排序
result.sort(key=compare)
# 构建输出字符串
output = ''.join([f"{item.ch}{item.count}" for item in result])
print(output)
if __name__ == "__main__":
main()
java
import java.util.*;
public class Main {
// 定义一个类存储字符及其次数
static class CharCount {
char ch;
int count;
CharCount(char ch, int count){
this.ch = ch;
this.count = count;
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
// 去除非字母字符并转换为小写
StringBuilder cleanBuilder = new StringBuilder();
for(char c: s.toCharArray()){
if(Character.isLetter(c)){
cleanBuilder.append(Character.toLowerCase(c));
}
}
String clean = cleanBuilder.toString();
List<CharCount> result = new ArrayList<>();
int n = clean.length();
int i =0;
while(i < n){
char current = clean.charAt(i);
int count =1;
int j = i +1;
// 统计连续字符
while(j < n && clean.charAt(j) == current){
count++;
j++;
}
if(count >1){
result.add(new CharCount(current, count));
i = j;
}
else{
// 非连续字符,统计后续出现次数
int cnt =0;
for(int k = i+1; k < n; k++){
if(clean.charAt(k) == current){
cnt++;
}
}
result.add(new CharCount(current, cnt));
i++;
}
}
// 自定义排序
Collections.sort(result, new Comparator<CharCount>(){
public int compare(CharCount a, CharCount b){
if(a.count != b.count){
return b.count - a.count; // 数字大的在前
}
return a.ch - b.ch; // 字母小的在前
}
});
// 构建输出字符串
StringBuilder output = new StringBuilder();
for(CharCount item: result){
output.append(item.ch).append(item.count);
}
System.out.println(output.toString());
}
}
题目描述
给定一个字符串的摘要算法,请输出给定字符串的摘要值
去除字符串中非字母的符号。
如果出现连续字符(不区分大小写) ,则输出:该字符 (小写) + 连续出现的次数。
如果是非连续的字符(不区分大小写),则输出:该字符(小写) + 该字母之后字符串中出现的该字符的次数
对按照以上方式表示后的字符串进行排序:字母和紧随的数字作为一组进行排序,数字大的在前,数字相同的,则按字母进行排序,字母小的在前。
输入描述
一行字符串,长度为[1,200]
输出描述
摘要字符串
样例1
输入
aabbcc
输出
a2b2c2
样例2
输入
bAaAcBb
输出
a3b2b2c0
说明
bAaAcBb: 第一个 b 非连续字母,该字母之后字符串中还出现了 2 次(最后的两个 Bb ) ,所以输出 b2
a 连续出现 3 次,输出 a3 , c 非连续,该字母之后字符串再没有出现过 c ,输出 c0
Bb 连续 2 次,输出 b2
对 b2a3c0b2 进行排序,最终输出 a3b2b2c0