题目描述:
有一种简易压缩算法:针对全部为小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。 例如字符串aaabbccccd 经过压缩变成字符串 3abb4cd 请您编写解压函数,根据输入的字符串, 判断其是否为合法压缩过的字符串 若输入合法则输出解压缩后的字符串 否则输出字符串!error来报告错误
输入描述:
输入一行,为一个 ASCII 字符串 长度不超过100字符 用例保证输出的字符串长度也不会超过100字符串
输出描述:
若判断输入为合法的经过压缩后的字符串 则输出压缩前的字符串 若输入不合法 则输出字符串!error
示例1:
输入:
4dff
输出
ddddff
说明
4d扩展为dddd,故解压后的字符串为ddddff.
示例2:
输入:
2dff
输出
!error
说明
两个d不需要压缩,故输入不合法
示例3:
输入:
4d@A
输出
!error
说明
全部由小写英文字母组成的字符串压缩后不会出现特殊字符@和大写字母A,故输入不合法。?
package com.tarena.test.B10;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**?
?* @author Administrator
?*
?*/
public class B17 {
?? ?public static void main(String[] args) {
?? ??? ?try(Scanner sc = new Scanner(System.in)){
?? ??? ??? ?String str = sc.nextLine();
?? ??? ??? ?System.out.println(resultStr(str));
?? ??? ??? ?
?? ??? ?}
?? ??? ?//System.out.println(zip("dddddddddddddfffeeeeg"));//13df4eg
?? ?}
?? ?
?? ?public static String resultStr(String str) {
?? ??? ?String backupStr = str;
?? ??? ?//只有数字,与小写字符
?? ??? ?if(!str.matches("[0-9a-z]+")) {
?? ??? ??? ?return "!error";
?? ??? ?}
?? ??? ?//正则验证,只有小数与小写字符的格式
?? ??? ?Pattern p = Pattern.compile("(\\d+)([a-z])");
?? ??? ?while(true) {
?? ??? ??? ?Matcher ma = p.matcher(str);
?? ??? ??? ?if(!ma.find()) {
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?String temp = ma.group();
?? ??? ??? ?int num = Integer.parseInt(ma.group(1));
?? ??? ??? ?if(num<3) {
?? ??? ??? ??? ?return "!error";
?? ??? ??? ?}
?? ??? ??? ?String valueStr = ma.group(2);
?? ??? ??? ?if(null == valueStr) {
?? ??? ??? ??? ?return "!error";
?? ??? ??? ?}
?? ??? ??? ?StringBuilder sb = new StringBuilder();
?? ??? ??? ?for(int i=0;i<num;i++) {
?? ??? ??? ??? ?sb.append(valueStr);
?? ??? ??? ?}
?? ??? ??? ?str = str.replace(temp, sb.toString());
?? ??? ?}
?? ??? ?//重新压缩,匹配
?? ??? ?if(!zip(str).equals(backupStr)) {
?? ??? ??? ?return "!error";
?? ??? ?}
?? ??? ?
?? ??? ?return str;
?? ?}
?? ?public static String zip(String str) {
?? ??? ?StringBuilder sb = new StringBuilder();
?? ??? ?int repeat = 0;
?? ??? ?int l=0,r=0;
?? ??? ?int len = str.length();
?? ??? ?char[] arr = str.toCharArray();
?? ??? ?while(r<len) {
?? ??? ??? ?if(arr[l]==arr[r]) {
?? ??? ??? ??? ?r++;
?? ??? ??? ??? ?repeat++;
?? ??? ??? ??? ?sb.append(arr[l]);
?? ??? ??? ??? ?continue;
?? ??? ??? ?}else {
?? ??? ??? ??? ?if((r-l)>2) {
?? ??? ??? ??? ??? ?sb.delete(sb.length()-repeat, sb.length());
?? ??? ??? ??? ??? ?sb.append(repeat).append(arr[l]);
?? ??? ??? ??? ?}else if((r-l)==2){? ? ? ??
?? ??? ??? ??? ??? ??? ?sb.append(arr[l]);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?repeat=0;
?? ??? ??? ??? ?l=r;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ?}
?? ??? ?//处理最后重复字母的
?? ??? ?if(repeat>2) {
?? ??? ??? ?sb.delete(sb.length()-repeat, sb.length());
?? ??? ??? ?sb.append(repeat).append(arr[l]);
?? ??? ?}
?? ??? ?return sb.toString();
?? ?}
?? ?
?? ?
?? ?public static String resultStr1(String str) {
?? ??? ?if(!str.matches("[0-9a-z]+")) {
?? ??? ??? ?return "!error";
?? ??? ?}
?? ??? ?char[] arr = str.toCharArray();
?? ??? ?StringBuilder re = new StringBuilder();
?? ??? ?int num = 0;
?? ??? ?for(int i=0,len=arr.length;i<len;i++) {
?? ??? ??? ?char c = arr[i];
?? ??? ??? ?if(isNum(c)) {
?? ??? ??? ??? ?num = Integer.valueOf(num+""+c);
?? ??? ??? ?}else {
?? ??? ??? ??? ?if(isLowerLetter(c)) {
?? ??? ??? ??? ??? ?re.append(extendStr(num,c));
?? ??? ??? ??? ??? ?num=0;
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ??? ?return re.toString();
?? ?}
?? ?
?? ?public static boolean isLowerLetter(char c) {
?? ??? ?return (c>='a'&&c<='z');
?? ?}
?? ?
?? ?public static boolean isNum(char c) {
?? ??? ?if(c>='0'&&c<='9') {
?? ??? ??? ?return true;
?? ??? ?}
?? ??? ?return false;
?? ?}
?? ?
?? ?public static String extendStr(int num,char c) {
?? ??? ?if(num>0&&num<3) {
?? ??? ??? ?return "!error";
?? ??? ?}
?? ??? ?StringBuilder sb = new StringBuilder().append(c);
?? ??? ?for(int i=1;i<num;i++) {
?? ??? ??? ?sb.append(c);
?? ??? ?}
?? ??? ?return sb.toString();
?? ?}
}
?
了解知识点
1、正则表达式的使用 字符串匹配表达式或Pattern类匹配字符串。