无意间看到了腾讯笔试题,点进去后发现一个有趣的题目。还挺有意思的,所以分享分享~
首先我们来看看原题的描述吧
描述
小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串太长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,
对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],
现在小A收到了小Q发送过来的字符串,你能帮助他进行解压缩么?
输入 : "HG[3|B[2|CA]]F"
输出 : "HGBCACABCACABCACAF"
解释 : HG[3|B[2|CA]]F −−> HG[3|BCACA]F −−> HGBCACABCACABCACAF
第一,我们先分析分析压缩的这段字符串的格式。
格式:[m|S](m为一个整数且1<=m<=100)
第二,明白格式之后自然就是如何把[ ]里需要重复的字符和重复次数提取出来。
1.遍历字符串肯定是首要的。
2.再思考如何正确截取字符串以获取到我们所需要的数据。
根据压缩版字符串的格式我们先正序地遍历,直到碰到第一个' ] ',然后 我们再倒序地遍历字符串直到碰到' | ',根据格式我们知道' | '到刚才碰到的' ] '这中间的字符就是我们需要的重复字符串,而' | '前面的就是需要重复的次数。然后再继续往前遍历直到' [ '。根据这个思路然后依次获取。
第三,那就是设计算法完成程序啦。
话不多说,直接上代码~
public class exercise {
public static void main(String[] args) {
String s1 = "GGB[2|D[3|BA]]CC";
String s2="HG[3|B[2|CA]]F";
System.out.println(s1+" 解压后为-->"+myMethod(s1));;
System.out.println(s2+" 解压后为-->"+myMethod(s2));;
}
public static String myMethod(String Message){
StringBuilder result=new StringBuilder();
for (int i = 0; i < Message.length(); i++) {
if(Message.charAt(i)!=']'){//先往result里面一直append,直到遇到"]"
result.append(Message.charAt(i));
}else {//然后我们开始从后面往前面遍历
String time;//用来存取下面捕获到"|"前面的数字,也就是"|"后面的字符串需要重复的次数
StringBuilder targetstr=new StringBuilder();//这个是用来存取"|"后面的字符串,也就是需要重复的字符串
int last_index=result.length()-1;//这个是用来保存我们需要重复的字符串的最后一个字母的下标的值
int j=result.length()-1;//这个用来保存需要重复的字母的第一个字母的下标,这样我们就能用subString(j+1,last_index)得到需要重复的字母串
while (result.charAt(j)!='['){
if(result.charAt(j)=='|'){
targetstr.append(result.substring(j+1));
last_index=j;
}
--j;
}
time=result.substring(j+1,last_index);//重复的字数,但是此时还是一个字符型的“次数”
int times=Integer.parseInt(time);//将字符型的次数转化为整数
StringBuilder decompress = new StringBuilder();//用来保存我们重复times次的targetstr的全部字符串
for (int k = 0; k < times; k++) {
decompress.append(targetstr);
}
StringBuilder temp = new StringBuilder();
result=temp.append(result.substring(0,j)).append(decompress);
}
}
String strb_result=result.toString();
return strb_result;
}
}
运行结果:
代码里我都有详细地注释啦,有看不懂的同志非常欢迎来下方评论区提问哦~