我是这样写的,可能也不是最优的方法。 多指教!!
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
public class StringReplace {
/**
* 需求分析:一个abc三种小写字母组成的字符串,当ab或ba出现时可以用c替换,
* 当ac或ca出现时可以用b替换,当bc或cb出现时可以用a替换。
* 尽可能让字符串的长度变短。
*
* 例: aaaabbbccccccc
* 替换后: c
*
* 思路:1,对字符串格式校验(字符串是否为空和是否包含除abc外的字母等)。否(不合格),提示该字符串不合格。是,执行下面操作。
* 2,判断字符中是否包含两种字母(因为只有包含两种字母才能进行替换操作)。否,提示该字符串无需优化。是,执行下面操作。
* 3,获取字符串中出现次数最多的字母,并从该字母开始替换。
* 4,每次替换完后重复2,3的操作。
*/
public static void main(String[] args) {
String str="aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbcccccccccccccccccccc";
// String str="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacccccccccccccccccc";
Begin(str);
}
private static void Begin(String str) {
boolean flag=getContains(str);//检查字符是否包含两种字母。
if(!flag){
throw new RuntimeException("字符串非法或无需优化!!");
}
int count=0;//用于记录替换次数
while(flag){
System.out.println(" 字符串 str=" + str + " 长度为:" + str.length());
char ch=getCharMaxnum(str); //获取出现次数最多的字母
System.out.println("每次出现次数最多的字母:"+ch);
str=stringReplace(str,ch);//对字符串按规则进行替换
System.out.println(" 替换"+ (++count) + "次后str:" + str + " 长度为:" + str.length());
System.out.println("============================================");
System.out.println();
flag=getContains(str);//检查字符是否包含两种字母。
}
}
/**
* 对字符串按规则进行替换 ab|ba ->c ac|ca ->b bc|cb->a
* */
private static String stringReplace(String str,char ch) {
String regexA="(ab|ba)";
String regexB="(bc|cb)";
String regexC="(ac|ca)";
switch(ch){
case'a':{
str=str.replaceAll(regexA, "c");
str=str.replaceAll(regexC, "b");
break;
}
case'b':{
str=str.replaceAll(regexB, "a");
str=str.replaceAll(regexA, "c");
break;
}
case'c':{
str=str.replaceAll(regexC, "b");
str=str.replaceAll(regexB, "a");
break;
}
}
return str;
}
/**
* 判断字符串是否包含两种字母
* */
private static boolean getContains(String str) {
if(str==null || "".equals(str)){
throw new RuntimeException("字符串为空!!");
}
if(str.contains("a") && str.contains("b")){
return true;
}
else if(str.contains("a") && str.contains("c")){
return true;
}
else if(str.contains("b") && str.contains("c")){
return true;
}
return false;
}
/**
* 获取出现次数最多的字母
* */
private static char getCharMaxnum(String str) {
if(str==null || "".equals(str)){
throw new RuntimeException("字符串为空!!");
}
char ch[] = str.toCharArray();
Map<Character,Integer> map=new TreeMap<Character,Integer>();
for(int i=0;i<ch.length;i++){
switch(ch){
case 'a': {
if(map.get('a')==null){
map.put('a',1);
break;
}
map.put('a',map.get('a')+1);
break;
}
case 'b':{
if(map.get('b')==null){
map.put('b',1);
break;
}
map.put('b',map.get('b')+1);
break;
}
case 'c':{
if(map.get('c')==null){
map.put('c',1);
break;
}
map.put('c',map.get('c')+1);
break;
}
default :{
throw new RuntimeException("该字符串包含非法字符!!!");
}
}
}
//对象存储字母和个数的map进行排序
List list=new ArrayList(map.entrySet());
Collections.sort(list,new Comparator(){
public int compare(Object o1, Object o2) {
Map.Entry entry1=(Map.Entry)o1;
Map.Entry entry2=(Map.Entry)o2;
return ((Integer)entry1.getValue()).compareTo((Integer)entry2.getValue());
}
});
for(int i=0; list!=null && i<list.size();i++){
Map.Entry<Character, Integer> entry=(Entry<Character, Integer>) list.get(i);
System.out.print(" " + entry.getKey()+":"+entry.getValue() + " ");
if(list.size()==1){
return entry.getKey();
}
if(i==list.size()-1){
return entry.getKey();
}
}
return 0;
}
}
|