#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