使用JAVA生成一个字母+数字的自增序列

使用JAVA生成一个字母+数字的自增序列

基本需求

需求:需要生成一个6位的自增序列,并且自增序列中的字母排除掉IOSVZ
格式要求:

  • 先用数字进行自增,如:000001到999999。
  • 如果6位都是数字并且达到最大值999999时,再次递增时,把第一位修改位字母A,后面5位从00001开始,如:A00001到A99999,如果后5位达到最大值99999时,首位字母自增为B,以此类推首位字母最大是Y。
  • 当首位字母是Y,数字达到99999,前两位修改为字母YA,后4位是数字从0001开始,最大是YY9999。再以此类推生成最大的自增序列是YYYYYY。

示例输出:000001 000002 … 999999 A00001 A00002 … A99999 B00000 B00001 … B99999 … Y00000 Y00001 … Y99999 YA0000 … YYYYYY

import java.util.HashMap;
import java.util.Map;

public class SequenceGenerator {
    // 定义要排除的字符数组,这些字符可能会在某些特定的场景下引起混淆或不希望被使用
    private static final char[] EXCLUDE_CHARS = {'I', 'O', 'S', 'V', 'Z'};

    // 定义字母表数组,包含了A到Z的所有大写字母,用于字符索引映射的初始化
    private static final char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

    // 定义字符索引映射,将每个字母映射到其在字母表中的位置,便于快速查找和处理
    private static final Map<Character, Integer> CHAR_INDEX_MAP = new HashMap<>();

    // 定义一个布尔数组,用于快速判断一个字符是否是有效的(即是否在字母表中且不在排除列表中)
    // 128是ASCII字符集的大小,因此这个数组覆盖了所有ASCII字符的判断
    private static final boolean[] VALID_CHAR = new boolean[128];

    // 静态初始化块,用于初始化字符映射和有效字符数组
    static {
        // 遍历ALPHABET数组,为每个字符在CHAR_INDEX_MAP中创建映射,并在VALID_CHAR中标记为有效
        for (int i = 0; i < ALPHABET.length; i++) {
            CHAR_INDEX_MAP.put(ALPHABET[i], i);
            VALID_CHAR[ALPHABET[i]] = true;
        }
        // 遍历EXCLUDE_CHARS数组,将这些字符在VALID_CHAR中标记为无效
        for (char c : EXCLUDE_CHARS) {
            VALID_CHAR[c] = false;
        }
        // 遍历数字字符(0-9),在VALID_CHAR中标记为有效
        for (int i = '0'; i <= '9'; i++) {
            VALID_CHAR[i] = true;
        }
    }

    /*
     * 需求:需要生成一个6位的自增序列,并且自增序列中的字母排除掉IOSVZ
     * 格式要求:先用数字进行自增,如:000001到999999。
     * 如果6位都是数字并且达到最大值999999时,再次递增时,把第一位修改位字母A,后面5位从00001开始,如:A00001到A99999,如果后5位达到最大值99999时,首位字母自增为B,以此类推首位字母最大是Y。
     * 当首位字母是Y,数字达到99999,前两位修改为字母YA,后4位是数字从0001开始,最大是YY9999。再以此类推生成最大的自增序列是YYYYYY。
     * 示例输出:000001 000002 ... 999999 A00001 A00002 ... A99999 B00000 B00001 ... B99999 ... Y00000 Y00001 ... Y99999 YA0000 ... YYYYYY
     */
    public static String increment(String sequence) {
        int maxLength = sequence.length();
        // 验证输入字符的有效性
        for (char c : sequence.toCharArray()) {
            if (!VALID_CHAR[c]) {
                throw new IllegalArgumentException("Invalid character in sequence: " + c);
            }
        }
        // 检查是否全为数字
        if (sequence.matches("\\d{" + maxLength + "}")) {
            long num = Long.parseLong(sequence);
            if (num <  Math.pow(10, maxLength)) {
                return String.format("%0"+maxLength+"d", num + 1);
            }
        }
        // 处理包含字母的情况
        StringBuilder sb = new StringBuilder(sequence);
        int index = maxLength-1;
        while (index >= 0) {
            char c = sb.charAt(index);
            if (Character.isDigit(c) && !(index==0 && c=='9')) {
                if (c == '9') {
                    sb.setCharAt(index, '0');
                    index--;
                } else {
                    sb.setCharAt(index, (char) (c + 1));
                    break;
                }
            } else {
                //当前字符为字母,判断下一个字母是否可用,如果不可用,则将当前字母替换为下一个可用字母,并将后续的数字字符重置为0,然后继续处理前一个字符。
                //如果当前字母集合最后一个,并且不可用时,
                int letterIndex = getLetterIndex(c);
                if (letterIndex < ALPHABET.length - 1) {
                    char nextValidChar = getNextValidChar(ALPHABET[letterIndex + 1]);
                    if(!VALID_CHAR[nextValidChar] && ALPHABET[ALPHABET.length-1]==nextValidChar){
                        sb.setCharAt(++index, getNextValidChar('A'));
                    }else {
                        sb.setCharAt(index, nextValidChar);
                    }
                    // 重置后续的数字字符
                    for (int j = index + 1; j < maxLength; j++) {
                        sb.setCharAt(j,nextValidChar==ALPHABET[0] && j==maxLength-1?'1':'0');
                    }
                    break;
                } else {
                    sb.setCharAt(index, getNextValidChar('A'));
                    index--;
                }
            }
        }
        if (index < 0) {
            throw new IllegalStateException("Sequence overflow: " + sequence);
        }
        return sb.toString();
    }

    /**
     * 获取字符在字母表中的索引
     *
     * @param c 要查询的字符
     * @return 字符在字母表中的索引,如果不存在,则返回-1
     */
    private static int getLetterIndex(char c) {
        Integer index = CHAR_INDEX_MAP.get(c);
        if (index == null) {
            index = -1;
        }
        return index;
    }

    /**
     * 获取给定字符的下一个有效字符
     *
     * @param c 起始字符
     * @return 下一个有效字符
     */
    private static char getNextValidChar(char c) {
        while (c < 'Z' && !VALID_CHAR[c]) {
            c++;
        }
        return c;
    }

    public static void main(String[] args) {
        String start = "999989";
        for (int i = 0; i <= 1000; i++) { // 生成100个序列
            System.out.println(start);
            start = increment(start);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值