【华为OD题库-016】字符串摘要-Java

发布于:2025-03-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

给定一个字符串的摘要算法,请输出给定字符串的摘要值
1、去除字符串中非字母的符号
2、如果出现连续字符(不区分大小写),则输出:该字符(小)+连续出现的次数
3、如果是非连续的宁符(不区分大小写),则输出:该字符(小写)该字母之后字符串中出现的该字符的次数
4、对按照以上方式表示后的字符串进行排序:字母和紧随的数字作为一组进行排序,数字大的在前,数字相同的则按字母进行排序,字母小的在前。
输入描述:
行字符串,长度为[1,200]
输出描述:
摘要字符串
示例1
输入:
aabbcc
输出:
a2b2c2
示例2
输入:
bAaAcBb
输出:
a3b2b2c0
说明:
第一个b非连续字母,该字母之后字符串中还出现了2次(最后的两个Bb),所以输出b2。a连续出现3次,输出a3,c非连续,该字母之后字符串再没有出现过c,输出c0,Bb连续2次,输出b2
对b2、a3、c0、b2进行排序,最终输出a3b2b2c0

 Java代码

 

package odTest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
//import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;

public class strAbstract {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		char[] strList = scanner.nextLine().toCharArray();
		
		//用于存放已存在的大小写字符,防止重复计算
		HashSet<String> set = new HashSet<>();
		//用于存放最终的 字母+次数列表
		List<String> list = new ArrayList<>();
		for(int i=0;i<strList.length;i++) {
			//计数
			int count = 0;
			//作用:判断每一次当前循环,是否属于此字母的大小写。
			String line = "";
			//作用:记录当前字母,连续与不连续出现的次数的字符串
			String countStr = "";
			//由于题目是输出小写字母,我在一开始把小写字母保存下来,大写变小写
			String downLetter = "";
			// 只要集合里存在这个字母的大小写,说明已经判断过了,直接跳过
			if(set.contains(strList[i]+"")) {
				continue;
			}
			//这里判断当前字母,并将大小写字母分别加入到set集合,然后,把当前字母的大小写存在line中,以便判断后续字母否是属于当前字母。
			//并将小写字母给赋值了
			if(strList[i]>='a'&&strList[i]<='z') {
				set.add(strList[i]+"");
				set.add(Character.toString((char) (strList[i]-32))+"");
				line = strList[i]+" "+(Character.toString((char) (strList[i]-32)));
				downLetter = strList[i]+"";
			}else {
				set.add(strList[i]+"");
				set.add(Character.toString((char) (strList[i]+32))+"");
				line = strList[i]+" "+(Character.toString((char) (strList[i]+32)));
				downLetter = Character.toString((char) (strList[i]+32));
			}
			//这里循环,当前字母后面的字母,判断,出现的次数
			for(int j=i;j<strList.length;j++) {
				if(line.contains(strList[j]+"")) {
					count = count+1;
					//这里很关键!当下一个不是当前字母的时候,直接把当前计数存入countStr,这样就可以通过数组区分是间断,还是连续。
					if(j+1>=strList.length||!line.contains(strList[j+1]+"")) {
						countStr = countStr+count+" ";
						count = 0;
					}
				}
			}
			//这里把记录字符串中的记录提取出来,如果长度为1,就是连续的,长度大于1就不连续需要进一步处理。
			int[] countList = Arrays.stream(countStr.split(" ")).mapToInt(Integer::parseInt).toArray();
			if(countList.length==1&&countList[0]==1) {
				list.add(downLetter+" "+0);
				continue;
			}else if(countList.length==1&&countList[0]>1) {
				list.add(downLetter+" "+countList[0]);
				continue;
			}
			//进一步处理,循环将不是最后一个值的累计。
			for(int n = 0;n<countList.length;n++) {
					if(n+1==countList.length&&countList[n]==1) {
						list.add(downLetter+" "+0);
						continue;
					}else if(n+1==countList.length&&countList[n]>1){
						list.add(downLetter+" "+countList[n]);
						continue;
					}
					//由于题目要求,需要跳过当前,判断后面字母出现和。
					int[] current = Arrays.copyOfRange(countList, n+1, countList.length);
					int sum = Arrays.stream(current).sum();
					list.add(downLetter+" "+sum);
			}
		}
		//这里排序
		Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
            	int o1Array = Integer.parseInt(o1.split(" ")[1]);
            	int o2Array = Integer.parseInt(o2.split(" ")[1]);
            	if(o1Array<o2Array) {
            		return 1;
            	}
            	if(o1Array == o2Array) {
            		return o1.compareTo(o2);
            	}
				return -1;
          	
            }
        }); 
		list.forEach(m->{
			m = m.replace(" ", "");
			System.out.print(m);
		});
	}
	

}