I'm working on developing an application to shorten links. Part of that requires me to be able to get the "next" string based on an allowed character ranges, as if we were counting up. Characters go from A-Z
to a-z
to 0-9
. Some samples:
"A" => "B"
"AA" => "AB"
"AZ" => "Aa"
"Az" => "A0"
"A9" => "BA"
"999" => "AAAA"
I've written a small class to accomplish this. My main concerns are the way I've hard-coded the ranges, and I'm not sure if doing this recursively made the most sense.
package proceduralstring;
/**
* Char succession: A-Z a-z 0-9
* @author User
*
*/
public class ProceduralStringCreator {
public static String getFirst(){
return "A";
}
public static String getFirst(int minLength){
StringBuilder result = new StringBuilder();
for(int i=0; i<minLength; i++){
result.append("A");
}
return result.toString();
}
public static String getNext(String current) throws BadFormatException{
if(!current.matches("[a-zA-Z0-9]+")){
throw new BadFormatException("String contains illegal characters.");
}
if(current.matches("9{"+current.length()+"}")){
return getFirst(current.length()+1);
}
StringBuilder result = new StringBuilder(current);
replaceWithNext(result, result.length()-1);
return result.toString();
}
private static StringBuilder replaceWithNext(StringBuilder toReplace, int index){
char currentChar = toReplace.charAt(index);
if(currentChar != '9'){ //base case
if(currentChar != 'z' && currentChar != 'Z'){
toReplace.replace(index, index+1, ((char)(currentChar+1))+"");
}else{
if(currentChar == 'z'){
toReplace.replace(index, index+1, "0");
}else if(currentChar == 'Z'){
toReplace.replace(index, index+1, "a");
}
}
return toReplace;
}else{ //recursive case
toReplace.replace(index, index+1, "A");
return replaceWithNext(toReplace, index-1);
}
}
}
The code is tested and works as intended (the exception is the desired behavior, as there is an invalid character):
package proceduralstring;
public class ProcStringTest {
public static void main(String[] args) throws BadFormatException {
System.out.println("getFirst: "+ProceduralStringCreator.getFirst());
System.out.println("getFirst(5): "+ProceduralStringCreator.getFirst(5));
System.out.println("Next of A: "+ProceduralStringCreator.getNext("A"));
System.out.println("Next of AA: "+ProceduralStringCreator.getNext("AA"));
System.out.println("Next of AAA: "+ProceduralStringCreator.getNext("AAA"));
System.out.println("Next of A9: "+ProceduralStringCreator.getNext("A9"));
System.out.println("Next of Adhs3hdfh9: "+ProceduralStringCreator.getNext("Adhs3hdfh9"));
System.out.println("Next of 9: "+ProceduralStringCreator.getNext("9"));
System.out.println("Next of 99: "+ProceduralStringCreator.getNext("99"));
System.out.println("Next of Aas9s99: "+ProceduralStringCreator.getNext("Aas9s99"));
System.out.println("Next of 9z9999: "+ProceduralStringCreator.getNext("9z9999"));
System.out.println("Next of 9Z9999: "+ProceduralStringCreator.getNext("9Z9999"));
System.out.println("Next of AUHR(#H: "+ProceduralStringCreator.getNext("AUHR(#H"));
}
}
Output:
getFirst: A
getFirst(5): AAAAA
Next of A: B
Next of AA: AB
Next of AAA: AAB
Next of A9: BA
Next of Adhs3hdfh9: Adhs3hdfiA
Next of 9: AA
Next of 99: AAA
Next of Aas9s99: Aas9tAA
Next of 9z9999: 90AAAA
Next of 9Z9999: 9aAAAA
Exception in thread "main" proceduralstring.BadFormatException: String contains illegal characters.
at proceduralstring.ProceduralStringCreator.getNext(ProceduralStringCreator.java:24)
at proceduralstring.ProcStringTest.main(ProcStringTest.java:18)
Picked up JAVA_TOOL_OPTIONS: -Duser.language=en