35:字符串的展开

一、题目链接

http://noi.openjudge.cn/ch0107/35/

二、解题思路

三、实施步骤

四、Java程序

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

public class Main {
    /**
     * 按照题目要求展开给定的字符串
     *
     * @param text String类型的对象,代表给定字符串
     * @param p1   int类型的整数,代表展开方式
     * @param p2   int类型的整数,代表填充字符的重复个数
     * @param p3   int类型的整数,代表填充是顺序还是逆序
     * @return String类型的对象,代表text的展开结果
     */
    public String expand(String text, int p1, int p2, int p3) {
        StringBuilder ans = new StringBuilder(); // text的展开结果
        ans.append(text.charAt(0)); // ans的第一个元素肯定是text的第一个字符
        char[] chars = text.toCharArray(); // 将text的内容转存为字符数组处理
        int n = chars.length; // text中的字符个数
        char current; // text的当前字符
        char last; // text当前字符的前一个字符
        char next; // text当前字符的后一个字符
        boolean bothDigits; // 标记last和next是否均为数字
        boolean bothLowerCase; // 标记last和next是否均为小写字母
        /* 标记i代表chars数组中字符的位置,i从1开始,到n-2为止,更新步长为1 */
        for (int i = 1; i < n - 1; i++) {
            current = chars[i]; // 获取text的当前字符
            last = chars[i - 1]; // 获取current的前一个字符
            next = chars[i + 1]; // 获取current的后一个字符
            // 如果last和next均为数字,bothDigits为true,否则false
            bothDigits = (isDigit(last) && isDigit(next));
            // 如果last和next均为小写字母,bothLetters为true,否则false
            bothLowerCase = (isLowerCase(last) && isLowerCase(next));
            // 如果当前字符是-符号且前后均为数字或字母
            if (current == '-' && (bothDigits || bothLowerCase)) {
                int number = (next - last - 1) * p2; // 根据p2计算填充字符的重复个数
                if (number < 0) { // 如果后一个字符小于等于前一个字符
                    ans.append(current); // 将-符号推入ans中
                }
                else if (number == 0) { // 否则如果后一个字符比前一个字符大1
                    ans.append(next); // 将后一个字符推入ans中
                    i++; // 此时下标需要移动到后一个字符
                    if (i == n - 1) { // 如果已经到达最后一个字符
                        return ans.toString(); // 返回展开的结果
                    }
                }
                else { // 否则,可以展开
                    char[] elements = new char[number]; // 待推入ans中的填充元素集合
                    if (p1 == 3) { // 如果使用星号填充
                        Arrays.fill(elements, '*');
                    }
                    else { // 否则,使用数字或字母填充
                        int k = 1; // 填充元素相对于last的增长步长,初始时为1
                        /* 每p2个填充元素都是相同的 */
                        for (int j = 0; j < number; j = j + p2) {
                            /* 按步长填充元素 */
                            for (int t = 0; t < p2; t++) {
                                elements[j + t] = (char) (last + k);
                            }
                            k++; // 下一个填充元素相对于last的增长步长加1
                        }
                        if (bothLowerCase && p1 == 2) { // 如果前后字符均为字母且需要用大写字母填充
                            for (int j = 0; j < number; j++) {
                                elements[j] = (char) (elements[j] - 32);
                            }
                        }
                        if (p3 == 2) { // 如果填充的元素需要逆序
                            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]); // 将最后一个字符推入ans中
        return ans.toString();
    }

    public static void main(String[] args) {
        Main test = new Main();
        Scanner scanner = new Scanner(System.in);
        int p1 = scanner.nextInt();
        int p2 = scanner.nextInt();
        int p3 = scanner.nextInt();
        scanner.nextLine();
        String text = scanner.next();
        System.out.print(test.expand(text, p1, p2, p3));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

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

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

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

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

打赏作者

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

抵扣说明:

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

余额充值