JAVA中的字母数字增量算法

时间:2016-07-05 18:13:32

标签: java algorithm increment alphanumeric

我需要实现像字母数字增量算法一样 AAA001应该成为AAA002 AAA999应该成为AAB000,依此类推。

所有字母均为大写,字母为0-9。 它可以在字母数字字符串中的任何位置包含字母或字母。

虽然有一些规则,例如000或666不应该出现在一系列中。这可以在以后完成,但我需要基本逻辑来实现算法。

我看到很多人都不理解我的问题。 想象一下车辆的车牌号码,它只不过是一个字母数字系列,可以有一些排除的字符,如BB6660 - > 666,中间三联6是不允许的。

它应该支持不同的格式,如 -

    @@@##
    @#@@##
    1@#@@##
    @@@@####
    ##@@#@

    @ means alphabet A-Z
    # means numbers 0-9            

示例:

    AFG99 + 1= AFH00
    A2GF23 + 1 = A2GF24
    1A9AU99 + 1 = 1A9AV00
    AAZZ9999 + 1 = ABAA0000
    11AA9Z + 1 = 11AB0A

我需要某种数学解决方案,以便我可以在不使用字符增量的情况下轻松地进行数学运算。

我还需要两个范围之间的计数,例如AAA003和AA010之间有多少计数?

    AAA010 - AAA003 = 7 

我很感激帮助..

2 个答案:

答案 0 :(得分:3)

这里有3个解决方案:前两个是有些算术递增,而第三个是字符操作。

3个实现都通过了相同的单元测试:

 assertEquals("1DDA01A", MyClass.increment("1DDA00Z"));
 assertEquals("1A9AV00", MyClass.increment("1A9AU99"));
 assertEquals("AFH00", MyClass.increment("AFG99"));
 assertEquals("A2GF24", MyClass.increment("A2GF23"));
 assertEquals("ABAA0000", MyClass.increment("AAZZ9999"));
 assertEquals("11AB0A", MyClass.increment("11AA9Z"));

<强>首先

public static String increment(String number) {
    Pattern compile = Pattern.compile("^(.*?)([9Z]*)$");
    Matcher matcher = compile.matcher(number);
    String left="";
    String right="";
    if(matcher.matches()){
         left = matcher.group(1);
         right = matcher.group(2);
    }
    number = !left.isEmpty() ? Long.toString(Long.parseLong(left, 36) + 1,36):"";
    number += right.replace("Z", "A").replace("9", "0");
    return number.toUpperCase();
}

<强>第二

public static String increment(String number) {
    Pattern compile = Pattern.compile("^(.*?)([0-9]*|[A-Z]*)$");
    Matcher matcher = compile.matcher(number);
    String remaining = number;
    String currentGroup = "";
    String result = "";

    boolean continueToNext = true;
        while (matcher.matches() && continueToNext) {
        remaining = matcher.group(1);
        currentGroup = matcher.group(2);
        int currentGroupLength = currentGroup.length();
        int base = currentGroup.matches("[0-9]*") ? 10 : 36;
        currentGroup = Long.toString(Long.parseLong("1" + currentGroup, base) + 1, base);  // The "1" if just to ensure that "000" doesn't become 0 (and thus losing the original string length)
        currentGroup = currentGroup.substring(currentGroup.length() - currentGroupLength, currentGroup.length());
        continueToNext = Long.valueOf(currentGroup, base) == 0;
        if (base == 36) {
            currentGroup = currentGroup.replace("0", "A");
        }

        result = currentGroup + result;
        matcher = compile.matcher(remaining);
    }

    result = remaining + result;
    return result.toUpperCase();
}

第三次

这适用于您当前的&#34; reqs&#34;。与开头提出的问题的问题相比,这不仅仅是一个由字母组成的左边部分&#34; +&#34;右边部分由数字组成&#34;。现在,它已经&#34;任何事情都发生了#34;,字母从A到Z滚动到A,而数字从0到9到0.当一个字母到达Z时,它被重置为A,然后是左边的数字/字母递增。

如果所有数字都递增,则不会在左侧添加新数字。你没有在你的问题中提到这一点,但我相信你可以从这里解决这个问题:

public static String increment(String number) {
    char[] cars = number.toUpperCase().toCharArray();
    for (int i = cars.length - 1; i >= 0; i--) {
        if (cars[i] == 'Z') {
            cars[i] = 'A';
        } else if (cars[i] == '9') {
            cars[i] = '0';
        } else {
            cars[i]++;
            break;
        }
    }
    return String.valueOf(cars);
}

对于&#34; count&#34;,你的例子不足以掌握逻辑。它只算数字吗?这封信怎么样?它是否遵循baseXx?

AA010-AAA003 = 7,3 A与2 A的关系无关紧要? 我觉得你很明白你的要求是什么(即:作业......)

从技术上讲,这回答了最初被问到的问题(在此过程中经过了许多修改)。

答案 1 :(得分:0)

[doing] math and increment [alphanumerics] without using character increment可以分解成更简单的问题:考虑你的&#34;字母数字&#34;用混合基数编码的整数。这将从字母数字转换为整数,(math)操作(增量,计数:差异/减法)< em>整数,以及从整数字母数字的转换。
对于整数,请查看LongAdder。对于转换,你需要保留一系列基础 - 我建议从单位/小端开始,只使用易于迭代的东西,并能够保持(小)整数。从字母数字整数,从零开始。对于每个字符,添加其值。对于一封信,请保留不同字母的数量(字母大小,26表示现在使用的拉丁字母)作为该地方使用的基数,数字表示不同数字的数字(通常为10)。如果跟随另一个字符,则乘以该基数并重复 从整数字母数字的转换将是通常的divide&remainder(使用保留的基数) - 有一个问题:如何处理来自最重要的进位位置?

There are some rules though, like some 000 or 666 should not come in a series. That can be done later on并将杀死math