JAVA中的字母数字增量算法
我需要实现字母数字增量算法,例如
AAA001应该变成AAA002
AAA999应该变成AAB000,依此类推。
I need to implement alphanumeric increment algorithm like AAA001 should become AAA002 AAA999 should become AAB000 and so on.
所有字母都在大写字母为0-9。
它可以在字母数字字符串的任何位置包含字母或字母。
All alphabets are in uppercase and letters are from 0-9. It can contain alphabet or letter at any position in the alphanumeric string.
尽管有一些规则,例如一些000或666不应该出现在序列中。可以稍后完成,但是我需要实现该算法的基本逻辑。
There are some rules though, like some 000 or 666 should not come in a series. That can be done later on but I am in need of basic logic to implement the algorithm.
我看到很多人不明白我的问题。
试想一下,这只不过是一个字母数字系列的车辆的车牌号,它可以包含一些排除的字符,例如BB6660-> 666,不允许在两者之间使用三重6。
I see many people did not understand my question. Just imagine the Plate Number of a vehicle which is nothing but a alphanumeric series which can have some excluded characters like BB6660 -> 666, triple 6 in between is not allowed.
它应该支持不同的格式,例如-
It should support different formats like-
@@@##
@#@@##
1@#@@##
@@@@####
##@@#@
@ means alphabet A-Z
# means numbers 0-9
示例:
AFG99 + 1= AFH00
A2GF23 + 1 = A2GF24
1A9AU99 + 1 = 1A9AV00
AAZZ9999 + 1 = ABAA0000
11AA9Z + 1 = 11AB0A
我需要某种数学解决方案,以便我可以进行数学运算并轻松地对其进行递增,而无需使用字符增量。
I need some sort of mathematical solution so that I can do math and increment it easily without using character increment.
我还需要两个范围之间的计数,例如AAA003和AA010之间存在多少个计数?
I also need the count between the two ranges like how many counts are there between AAA003 and AA010 ?
AAA010 - AAA003 = 7
我将不胜感激。.
这里有3个解决方案:前两个是算术增量,而第三是更多的字符演员操纵。
Here's 3 solutions: the first two are somewhat arithmetic incrementations while the third is more a character manipulations.
这三个实现都通过了相同的单元测试:
The 3 implementations all pass the same unit tests:
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();
}
第三:
这适用于您当前的要求。与开始时所问的问题相比,这不仅仅是由字母组成的左半部分 +由数字组成的右半部分。现在,一切皆有可能,字母从A滚动到Z到A,数字从0滚动到9到0。当字母到达Z时,它将重置为A,然后左侧的数字/字母递增。
This works with your current "reqs". Compared to how the question what asked at the beginning, this is not just a "left-part composed of letter" + "right part composed of digits". Now, it's "anything goes", and letters roll from A to Z to A, while digits from 0 to 9 to 0. When a letter reaches Z, it is reset to A, then the digit/letter on its left is incremented.
如果所有数字均递增,则不会在左侧添加新数字。您没有在问题中提到这一点,但我相信您可以从这里弄清楚:
If all numbers are incremented, it does not add a new digit on the left. You did not mention that in your question, but I'm sure you can figure this out from here:
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);
}
对于计数,您的示例不足以掌握逻辑。它仅计算数字吗?字母呢?它会遵循baseXx吗?
As for the "count", your example isn't sufficient to grasp the logic. Does it count only numbers ? what about the letters ? Does it follow a baseXx ?
AA010-AAA003 = 7、3 A与2 A没关系吗?
我觉得这是您要了解您的要求(即:家庭作业..)
how can AA010-AAA003 = 7, the 3 A's versus 2 A's do no matter ? I feel this is rather on you to understand what are your requirements (ie: homework..)
从技术上讲,这可以回答最初提出的问题(在此过程中进行了许多修改)。
Technically, this answers the question as it was asked originally (with many modifications along the way).