用java语言实现两个函数encode()和decode(),分别实现对字符串的变换和复原。变换函数encode()顺序考察已知字符串的字符,按以下规则逐组生成新字符串:

(1)若已知字符串的当前字符不是大于0的数字字符,则复制该字符于新字符串中。

(2)若已知字符串的当前字符是一个数字字符,且它之后没有后继字符,则简单地将它复制到新字符串中。

(3)若已知字符串的当前字符是一个大于0的偶数数字字符,并且还有后继字符,设该数字字符的面值为n,则将它的后继字符(包括后继字符是一个数字字符)重复复制n+1次到新字符串中;复制后判断该后继字符是否为大于0的数字字符,如果是,则跳过该后继字符。

(4)若已知字符串的当前字符是一个大于0的奇数数字字符,并且还有后继字符,设该数字字符的面值为n,则将它的后继字符(包括后继字符是一个数字字符)重复复制n+1次到新字符串中。

(5)若已知字符串的当前字符是下划线‘_’,则将当前字符串变换为用‘\UL’。

(6)以上述一次变换为一组,在不同组之间另插入一个下划线‘_’用于分隔。

例如:encode()函数对字符串:

12__4c_ab的变换结果为22_____\UL_\UL_ccccc_c_\UL_a_b

21的变换结果为111_

package com.demo.util;

import org.apache.commons.lang3.StringUtils;

/**
 * (1)若已知字符串的当前字符不是大于0的数字字符,则复制该字符于新字符串中。
 * (2)若已知字符串的当前字符是一个数字字符,且它之后没有后继字符,则简单地将它复制到新字符串中。
 * (3)若已知字符串的当前字符是一个大于0的偶数数字字符,并且还有后继字符,设该数字字符的面值为n,则将它的后继字符(包括后继字符是一个数字字符)重复复制n+1次到新字符串中;复制后判断该后继字符是否为大于0的数字字符,如果是,则跳过该后继字符。
 * (4)若已知字符串的当前字符是一个大于0的奇数数字字符,并且还有后继字符,设该数字字符的面值为n,则将它的后继字符(包括后继字符是一个数字字符)重复复制n+1次到新字符串中。
 * (5)若已知字符串的当前字符是下划线‘_’,则将当前字符串变换为用‘\UL’。
 * (6)以上述一次变换为一组,在不同组之间另插入一个下划线‘_’用于分隔。
 */
public class EnCodeAndDecode {

    //编码
    private static String enCode(String data) {
        if (StringUtils.isEmpty(data)) {
            return null;
        }
        //转成字符组
        char[] chars = data.toCharArray();
        int length = chars.length;
        StringBuffer responseStr = new StringBuffer();
        Integer num = 0;
        //是否跳过这次循环
        boolean jump = false;
        for (char c : chars) {
            num++;
            //条件(3)
            if (jump) {
                jump = false;
                continue;
            }
            //校验是否为数字
            if (Character.isDigit(c)) {
                //条件(1)
                if (c <= '0') {
                    responseStr.append(c);
                    continue;
                }
                //条件(2)
                if (num == length) {
                    responseStr.append(c);
                }
                //条件(3)(4)
                if (c > '0' && num < length) {
                    int n = Integer.parseInt("" + c) + 1;
                    char aChar = chars[num];
                    while (n > 0) {
                        responseStr.append(aChar);
                        n--;
                    }
                    //如果字符是偶数,复制后判断该后继字符是否为大于0的数字字符,如果是,则跳过该后继字符。
                    if (c % 2 == 0 && Character.isDigit(aChar) && aChar > '0') {
                        jump = true;
                    }
                }
            } else {
                //条件(5)
                if ('_' == c) {
                    responseStr.append("\\UL");
                } else {//其他隐含条件
                    responseStr.append(c);
                }
            }
            //条件(6)
            if (num < length) {
                responseStr.append("_");
            }

        }
        return responseStr.toString();
    }

    //解码
    public static String deCode(String enData) {
        if (StringUtils.isEmpty(enData)) {
            return null;
        }
        if (enData.indexOf("_") == -1) {
            return enData;
        }
        int nullValueNum = 0;
        StringBuffer data = new StringBuffer();
        for (String str : enData.split("_")) {
            if (str.length() == 1) {
                data.append(str);
            } else {
                if (str.length() == 0 || StringUtils.isEmpty(str)) {
                    nullValueNum++;
                    continue;
                }
                if (nullValueNum > 2) {
                    data.append(nullValueNum - 2);
                }
                nullValueNum = 0;
                if ("\\UL".equals(str)) {
                    data.append("_");
                } else {
                    int n = str.length() - 1;
                    data.append(n);
                    //如果是偶数
                    char c = str.charAt(0);
                    if (n % 2 == 0 && Character.isDigit(c) && c > '0') {
                        data.append(c);
                    }
                }
            }
        }
        return data.toString();
    }

    public static void main(String[] args) {
        String s = enCode("12__4c_ab");
        System.out.println(s);
        System.out.println(deCode(s));
    }
}