从命令行读入一个字符串,然后写encode和decode两个方法对字符串做以下处理:
encode方法
1字符串中含不大于0的数按原始那样不处理
2字符串中有大于0但是没有后继字符也按原始那样不处理
3字符串中有大于0但是有后继字符的,如n后面有字符,则处理为n+1个后继字符
4每次处理后都将加入“_”
5原始字符串中有“_”,将处理为“\UL”;如下所示:
_24g02_5hl4 转换为\UL_444_ggggg_0\UL\UL_hhhhhh_4decode方法相反\UL_444_ggggg_0\UL\UL_hhhhhh_4 转换为 _24g02_5hl4
encode方法
1字符串中含不大于0的数按原始那样不处理
2字符串中有大于0但是没有后继字符也按原始那样不处理
3字符串中有大于0但是有后继字符的,如n后面有字符,则处理为n+1个后继字符
4每次处理后都将加入“_”
5原始字符串中有“_”,将处理为“\UL”;如下所示:
_24g02_5hl4 转换为\UL_444_ggggg_0\UL\UL_hhhhhh_4decode方法相反\UL_444_ggggg_0\UL\UL_hhhhhh_4 转换为 _24g02_5hl4
不过既然写了就先贴出来了,有修正再上
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test {
public static void main(String[] args) {
String string = "_24g02_5hl4";
string = encode(string);
System.out.println(string);
string = decode(string);
System.out.println(string);
} /*
* encode方法 1字符串中含不大于0的数按原始那样不处理 2字符串中有大于0但是没有后继字符也按原始那样不处理
* 3字符串中有大于0但是有后继字符的,如n后面有字符,则处理为n+1个后继字符 4每次处理后都将加入“_”
* 5原始字符串中有“_”,将处理为“\UL”;
*/
public static String encode(String s) { StringBuffer rtn = new StringBuffer(); if (s == null) {
return rtn.toString();
} Pattern pattern = Pattern.compile("[1-9]{1}[\\w]{1}[.]*");
Matcher matcher = pattern.matcher(s);
//匹配字符串开始位置
int matcherIdx = 0;
//截取参数字符串开始位置
int startIdx = 0;
// 查找匹配字符类型为“数字+字符”
while (matcher.find(matcherIdx)) {
//取得匹配字符开始索引
int index = matcher.start();
//根据索引取得数字
int num = Integer.parseInt(String.valueOf(s.charAt(index)));
//根据索引取得字符
String str = String.valueOf(s.charAt(index + 1));
//把所有下划线替换为\UL
str = str.replace("_", "\\UL");
//如果有匹配字符串,把匹配字符串之前的内容添加到StringBuffer
if (startIdx < index) {
rtn.append(
s.substring(startIdx, index).replace("_","\\UL")
);
}
//根据取得的数字,添加相应数量的字符
for (int i = 0; i <= num; i++) {
rtn.append(str);
}
rtn.append("_");
//下次检索位置为当前位置+1
matcherIdx = index + 1;
//截取参数字符串开始位置为当前位置+2
startIdx = index + 2;
}
//添加剩余字符串
rtn.append(s.substring(startIdx));
return rtn.toString();
} // 逆转encode方法
public static String decode(String s) { StringBuffer rtn = new StringBuffer(); if (s == null) {
return rtn.toString();
} //根据下划线分割成数组
String[] arrStr = s.split("_");
/*判断之前最后一位是否为数字的标记
* 主要用于应对这种可能
* "_24gg02_5hl4" (假设有2个以上g之类的)
* 如果没有这种可能不需要这个标记,程序可简化*/
int numFlg = 0;
for (String str : arrStr) {
//还原\UL为下划线
str = str.replace("\\UL", "_");
int index = 0;
//分割字符串为单个字符的数组
char[] chars = str.toCharArray();
for (int i = 1; i < chars.length; i++) {
//记录下开始重复的字符串位置
if (chars[i]==(chars[i - 1])) {
index = i;
break;
}
}
//如果有重复字符
if (index > 0) {
rtn.append(str.substring(0, index - 1));
int cnt = str.substring(index).length();
if (numFlg == 0) {
rtn.append(cnt);
try {
numFlg = Integer.parseInt(String.valueOf(chars[index]));
} catch (NumberFormatException e) {
numFlg = 0;
} } else {
for (int i = numFlg; i < cnt; i++) {
rtn.append(chars[index]);
}
numFlg = 0;
}
rtn.append(chars[index]);
} else {
//没有重复字符则添加整个字符串
rtn.append(str);
}
}
return rtn.toString();
}
}
encode用了正则,decode没有用,其实不用正则也一样
不过匹配字符那个会麻烦点,可以这么来
还是用char[] chars = s.toCharArray();
然后循环每个查询,
判断如果是下划线,转成\UL添加到StringBuffer
如果是数字,判断是否大于0,大于0看数组是否到头了,没到头就取后一位的字符,根据数字循环往StringBuffer添加相应数量的字符(这里字符如果是下划线,替换成\UL),如果是0直接添加0
不是数字则直接添加然后在对应操作之后加上下划线就可以。
public static void main(String[] args) {
String string = "_24g02_5hl4";
String tmp = encode(string);
System.out.println(tmp);
String res = decode(tmp);
System.out.println(res);
} private static String encode(String string) {
char chs [] = string.toCharArray();
StringBuilder buff = new StringBuilder();
boolean changed = false;
for(int index=0;index<chs.length-1;index++){
if(checkNumber(chs[index])){
String ch = ""+chs[index+1];
if(chs[index+1]=='_')ch="\\UL";
for(int i=0;i<=chs[index]-'0';i++){
buff.append(ch);
}
buff.append('_');
changed=true;
continue;
}
if(changed){
changed=false;
}else{
if(chs[index]=='_'){
buff.append("\\UL_");continue;
}
buff.append(chs[index]);
}
}
if(checkNumber(chs[chs.length-2])==false){
buff.append(chs[chs.length-1]);
}
return buff.toString();
} private static boolean checkNumber(char c) {
return c>'0' && c<='9';
} private static String decode(String tmp) {
String [] subs = tmp.split("_");
StringBuilder buff = new StringBuilder();
for(String sub : subs){
char [] chs = sub.toCharArray();
if(chs[chs.length-1]==chs[chs.length-2]){
if(chs[0]!=chs[1]){
buff.append(chs[0]).append(chs.length-2).append(chs[1]);
}else{
buff.append(chs.length-1).append(chs[1]);
}
continue;
}
if(checkUnderLine(chs, chs.length-1)){
if(chs[0]!='\\'){
buff.append(chs[0]);
}
int count =0;
for(int index=chs.length-1;index>1;count++,index-=3);
if(count>1)buff.append(count-1);
buff.append('_');
continue;
}
buff.append(sub);
}
return buff.toString();
} private static boolean checkUnderLine(char [] chs,int lastIndex){
return chs.length-lastIndex>=1 && lastIndex>1 && chs[lastIndex]=='L' && chs[lastIndex-1]=='U' && chs[lastIndex-2]=='\\';
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test {
public static void main(String[] args) {
String string = "_24g02_5hl4";
string = encode(string);
System.out.println(string);
string = decode(string);
System.out.println(string);
string = encode2(string);
System.out.println(string);
} /*
* encode方法 1字符串中含不大于0的数按原始那样不处理 2字符串中有大于0但是没有后继字符也按原始那样不处理
* 3字符串中有大于0但是有后继字符的,如n后面有字符,则处理为n+1个后继字符 4每次处理后都将加入“_”
* 5原始字符串中有“_”,将处理为“\UL”;
*/
public static String encode(String s) { StringBuffer rtn = new StringBuffer(); if (s == null) {
return rtn.toString();
} Pattern pattern = Pattern.compile("[1-9]{1}[\\w]{1}[.]*");
Matcher matcher = pattern.matcher(s);
//匹配字符串开始位置
int matcherIdx = 0;
//截取参数字符串开始位置
int startIdx = 0;
// 查找匹配字符类型为“数字+字符”
while (matcher.find(matcherIdx)) {
//取得匹配字符开始索引
int index = matcher.start();
//根据索引取得数字
int num = Integer.parseInt(String.valueOf(s.charAt(index)));
//根据索引取得字符
String str = String.valueOf(s.charAt(index + 1));
//把所有下划线替换为\UL
str = str.replace("_", "\\UL");
//如果有匹配字符串,把匹配字符串之前的内容添加到StringBuffer
if (startIdx < index) {
rtn.append(
s.substring(startIdx, index).replace("_","\\UL")
);
}
//根据取得的数字,添加相应数量的字符
for (int i = 0; i <= num; i++) {
rtn.append(str);
}
rtn.append("_");
//下次检索位置为当前位置+1
matcherIdx = index + 1;
//截取参数字符串开始位置为当前位置+2
startIdx = index + 2;
}
//添加剩余字符串
rtn.append(s.substring(startIdx));
return rtn.toString();
} //不用正则
public static String encode2(String s) { StringBuffer rtn = new StringBuffer();
if (s == null) {
return rtn.toString();
}
char[] chars = s.toCharArray(); for (int i = 0; i < chars.length; i++) {
//如果是数字
if (Character.isDigit(chars[i]) && i < chars.length - 1 && Integer.valueOf(String.valueOf(chars[i]))>0) {
concat(rtn, chars[i+1], Integer.valueOf(String.valueOf(chars[i])));
rtn.append("_");
if (!Character.isDigit(chars[i+1])) {
i++;
}
} else {
concat(rtn, chars[i], 0);
}
}
return rtn.toString();
}
public static void concat(StringBuffer sBuffer, char c, int cnt) {
String concat = "";
if (c=='_') {
concat = "\\UL";
} else {
concat = String.valueOf(c);
}
for (int i = 0; i <= cnt; i++) {
sBuffer.append(concat);
}
}
// 逆转encode方法
public static String decode(String s) { StringBuffer rtn = new StringBuffer(); if (s == null) {
return rtn.toString();
} //根据下划线分割成数组
String[] arrStr = s.split("_");
/*判断之前最后一位是否为数字的标记
* 主要用于应对这种可能
* "_24gg02_5hl4" (假设有2个以上g之类的)
* 如果没有这种可能不需要这个标记,程序可简化*/
int numFlg = 0;
for (String str : arrStr) {
//还原\UL为下划线
str = str.replace("\\UL", "_");
int index = 0;
//分割字符串为单个字符的数组
char[] chars = str.toCharArray();
for (int i = 1; i < chars.length; i++) {
//记录下开始重复的字符串位置
if (chars[i]==(chars[i - 1])) {
index = i;
break;
}
}
//如果有重复字符
if (index > 0) {
rtn.append(str.substring(0, index - 1));
int cnt = str.substring(index).length();
if (numFlg == 0) {
rtn.append(cnt);
if (Character.isDigit(chars[index])) {
numFlg = Integer.parseInt(String.valueOf(chars[index]));
}
} else {
for (int i = numFlg; i < cnt; i++) {
rtn.append(chars[index]);
}
numFlg = 0;
}
rtn.append(chars[index]);
} else {
//没有重复字符则添加整个字符串
rtn.append(str);
}
}
return rtn.toString();
}
}
public static String decode2(String s) { StringBuffer rtn = new StringBuffer(); if (s == null) {
return rtn.toString();
} //去掉下划线
s = s.replace("_","");
//还原\UL为下划线
s = s.replace("\\UL", "_");
//转换成char数组
char[] chars = s.toCharArray(); //遍历循环
for (int i = 0; i < chars.length-1; i++) {
if (chars[i] == chars[i+1]) {
int cnt = 0;
if (i > 0 && Character.isDigit(chars[i-1]) && chars[i-1] != '0') {
i += Character.digit(chars[i-1], 10);
rtn.append(chars[i]);
} else {
for (int j = i+1; j < chars.length-1; j++) {
if (chars[j] == chars[i+1]) {
cnt++;
} else {
break;
}
}
i+=cnt;
rtn.append(cnt);
rtn.append(chars[i]);
}
} else {
rtn.append(chars[i]);
}
}
rtn.append(chars[chars.length-1]);
return rtn.toString();
}