35:字符串的展开

/**
 * 【题目名称】字符串的展开<p>
 * 【题目来源】http://noi.openjudge.cn/ch0107/35/
 *
 * @author 潘磊,just_panlei@just.edu.cn
 * @version 1.0
 */

import java.util.Arrays;
import java.util.Scanner;
import static java.lang.Character.isLowerCase;
import static java.lang.Character.isDigit;

public class Main {
    /**
     * 在指定展开方式、填充字符的重复个数、填充顺序或逆序条件下,展开指定的字符串。
     *
     * @param str 指定字符串。
     * @param p1  指定展开方式。
     * @param p2  指定填充字符的重复个数。
     * @param p3  指定填充顺序或逆序。
     * @return str的展开结果。
     */
    public String expand(String str, int p1, int p2, int p3) {
        StringBuilder ans = new StringBuilder(); // str的展开结果,初始为空
        char[] chars = str.toCharArray(); // 将str的内容转存为字符数组
        ans.append(chars[0]); // 将str的第一个字符先推入ans中
        int n = chars.length; // str中的字符个数
        char current; // 当前字符
        char last; // 当前字符的前一个字符
        char next; // 当前字符的后一个字符
        boolean isBothDigits; // 标记last和next是否均为数字
        boolean isBothLowerCase; // 标记last和next是否均为小写字母
        /* 从str的第二个字符依次遍历到第n-1个字符 */
        for (int i = 1; i < n - 1; i++) {
            current = chars[i]; // 获取当前字符
            last = chars[i - 1]; // 获取前序字符
            next = chars[i + 1]; // 获取后序字符
            // 如果last和next均为数字,标记isBothDigits为true,否则false
            isBothDigits = (isDigit(last) && isDigit(next));
            // 如果last和next均为小写字母,标记isBothLowerCase为true,否则false
            isBothLowerCase = (isLowerCase(last) && isLowerCase(next));
            // 如果当前字符是-符号,且last、next均为数字或小写字母
            if (current == '-' && (isBothDigits || isBothLowerCase)) {
                int number = (next - last - 1) * p2; // 根据p2计算填充字符的总数
                if (number < 0) { // 如果后一个字符小于等于前一个字符
                    ans.append(current); // 将-符号推入ans中
                    ans.append(next); // 将后一个字符推入ans中
                    i++; // 将下标移动到后一个字符的位置
                    if (i == n - 1) { // 如果已经到达str的尾部
                        return ans.toString(); // 返回展开的结果
                    }
                }
                else if (number == 0) { // 否则如果后一个字符比前一个字符大1
                    ans.append(next); // 将后一个字符推入ans中
                    i++; // 将下标移动到后一个字符的位置
                    if (i == n - 1) { // 如果已经到达str的尾部
                        return ans.toString(); // 返回展开的结果
                    }
                }
                else { // 否则,代表当前位置可以展开
                    char[] elements = new char[number]; // 待推入ans中的填充字符集合
                    if (p1 == 3) { // 如果使用星号填充
                        Arrays.fill(elements, '*'); // 设置elements数组为全*符号
                    }
                    else { // 否则,使用数字或小写字母填充
                        int k = 1; // 填充元素相对于last的增长步长,初始为1
                        /* 填充时,每p2个填充元素都是相同的 */
                        for (int j = 0; j < number; j += p2) {
                            /* 按当前增长步长k,填充p2个相同字符 */
                            for (int t = 0; t < p2; t++) {
                                elements[j + t] = (char) (last + k);
                            }
                            k++; // 下一个填充元素相对于last的增长步长加1
                        }
                        if (isBothLowerCase && p1 == 2) { // 如果前后字符均为小写字母且需要用大写字母填充
                            for (int j = 0; j < number; j++) {
                                elements[j] = (char) (elements[j] - 32); // 将填充元素改为大写字母
                            }
                        }
                        if (p3 == 2) { // 如果填充的元素需要逆序
                            /* 对elements数组做镜像反转 */
                            for (int j = 0; j < number / 2; j++) {
                                char t = elements[j];
                                elements[j] = elements[number - j - 1];
                                elements[number - j - 1] = t;
                            }
                        }
                    }
                    ans.append(elements); // 将填充字符集合推入ans
                }
            }
            else { // 否则,当前字符不是-符号
                ans.append(chars[i]); // 将当前字符推入ans中
            }
        }
        ans.append(chars[n - 1]); // 将str的尾部字符推入ans中
        return ans.toString();
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Main call = new Main();
        int p1 = scanner.nextInt();
        int p2 = scanner.nextInt();
        int p3 = scanner.nextInt();
        scanner.nextLine();
        String text = scanner.next();
        System.out.print(call.expand(text, p1, p2, p3));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江苏科技大学_计算机学院_潘磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值