# Incrementing alphanumeric string

Melinda Deering
Greenhorn
Posts: 11
I have an assignment where I need to increment an alphanumeric string by one. For example AAA123 + 1 = AAA124. I'm okay with incrementing alpha or incrementing numbers, but incrementing them all together is where I am stuck. Should I just convert the entire string to ascii and increment there? Any nudge in the right direction will be appreciated.

Henry Wong
author
Marshal
Posts: 21493
84

Should I just convert the entire string to ascii and increment there?

Well, that depends on what the definition of "incrementing" is. Obviously, incrementing a "1" becomes "2", but what happens to a "9" or a "Z"? What is the ordering between the letters and numbers?

And what will cause the next character (the one next to the last one) to be incremented? Meaning what is the order that will cause an overflow?

Henry

Melinda Deering
Greenhorn
Posts: 11
I'm sorry...I was not clear about what I meant by incrementing. I want to add one, so that AAA123 turns into AAA124. At first I considered incrementing the letters and numbers separately, but that will not help me in the case of AAA999 to AAB000. Clearly I need to treat the entire string as one number.

Rob Spoor
Sheriff
Posts: 20661
65
Not at first. First you try to increment the last character. If that would cause it to overflow, you increment the next, etc.

Campbell Ritchie
Sheriff
Posts: 50175
79
Is the String supposed to represent a hexadecimal number?

Melinda Deering
Greenhorn
Posts: 11
I'm not sure...I think ascii.

Henry Wong
author
Marshal
Posts: 21493
84
Melinda Deering wrote:I'm not sure...I think ascii.

I highly doubt that it goes through all the ASCII characters -- there are many control characters in the ASCII character set, then incrementing it straight may yield strings that are not really text strings.

Henry

Melinda Deering
Greenhorn
Posts: 11
Well, I would need to use 65-90 for upper case letters and 48-57 for numbers.

Campbell Ritchie
Sheriff
Posts: 50175
79
65-90? So you are using base 36 numbers? Or something like car registration numbers? Do you start from 1 and what happens after 9? Do you go on to 10 or A?

Do you remember when you were 7 years old and they taught you long addition at school? Can you remember about add 1, and carry 1?
Do you know how a several-number counter works? It is like long addition, only after getting to the top of the array you need the % operator to get back to the beginning.

Create a char[] array from 0 to 9 and A to Z, and a second 6-member array to hold the results.

Melinda Deering
Greenhorn
Posts: 11
It's actually a project to increment license plate numbers, so AAA123 becomes AAA124.

Rob Spoor
Sheriff
Posts: 20661
65
Don't use 65-90 but instead 'A'-'Z'. They are actually the same, but the latter reads easier.

Melinda Deering
Greenhorn
Posts: 11
I modified some code that someone shared with me that seems to do a similar kind of thing and I'll paste it below. It's not incrementing correctly, but I'm getting a tiny bit closer. I have commented where I believe I am going wrong. I want to be able to input a plate, and have it give me the next in sequence. (The instructor wants an input file, but I don't have any idea how to do those).

Henry Wong
author
Marshal
Posts: 21493
84
I modified some code that someone shared with me that seems to do a similar kind of thing and I'll paste it below.

When it comes to homework assignments, I am not a fan of this... you should do the assignment from scratch. There are two reasons for this...

1. You learn from the homework assignment. The more you figure it out yourself, the more you learn.

2. It is easier to fix something that you understand. The more code you borrow, the more code you may not understand, and hence, the more issues that you will encounter when you need to fix or modify the code.

Henry

Melinda Deering
Greenhorn
Posts: 11
Actually, I agree with you on this.

This is my third Java class. The first two classes were taught by a woman who had us write from scratch, of course, and gradually added on so all the parts made sense. This is my first assignment for a new course with an instructor I have never had before and I am in a total panic because he is requesting a number of concepts that I have never had any exposure to, such as ascii conversion, etc. My hope in posting is that someone will phrase something in a way that makes the concept stick for me....like converting characters to ascii.

Campbell Ritchie
Sheriff
Posts: 50175
79
ASCII conversion is really easy if you know the values each char represents. Remember a char is really an unsigned integer in the range 0-65535 (approx) inclusive. So you can do arithmetic on them. You can find out the values if you go to the Unicode website; the "basic Latin" page has values in identical to ASCII. They are written in hexadecimal, so you have to forget about 'A'=65. It is now 'A'=0x41.

Write out the following pseudocode and implement it; it tells you how many marks you are going to get.
• Take a String from the keyboard.
• Apply the method of the String class which produces a char[]; I think it is called toCharArray().
• Apply the % operator to each char: 'A' % 0x20 gives 1, 'B' % 0x20 gives 2, etc.
• You get the same results for lower-case letters, but that only works for the 26 English letters. It won't work for accents or cedillas or similar.
• 0x20 = space, so a space will count as a 0 when adding.
• Note that the results of those calculations are always ints.
• Try it with "hard work" and "knowledge" and see how far those will get you.

Try this for loop, remembering the (char) cast is essential:
You will now see you can create an array size '9' - '0' + 1 + 'z' - 'a' + 1. Remember 'z' - 'a' = 25. Better not to write 26, but let the computer do that arithmetic. Simple subtraction like that is a fast operation.

Now: try this lot
• Create a char[] array the size I told you earlier.
• Create an index variable initialised to 0.
• Set up a for-loop from '0' to '9'.
• Each iteration does 2 things. It sets up the present member of the array (characters[index]) equal to the char for the loop.
• The other thing it does is increments index by 1.
• Set up a second for-llop from 'A' to 'Z' and work out for yourself what goes in that loop.
• Print out all that array with the System.out.println() method and see what you have got
• Work out a better way which doesn't duplicate the for loop.
• Registration numbers usually only use capital letters.>

G.Sathish kumar
Ranch Hand
Posts: 84
Melinda Deering wrote:I have an assignment where I need to increment an alphanumeric string by one. For example AAA123 + 1 = AAA124. I'm okay with incrementing alpha or incrementing numbers, but incrementing them all together is where I am stuck. Should I just convert the entire string to ascii and increment there? Any nudge in the right direction will be appreciated.

i am not sure about the meaning of your add operation but try like get all last numberic like AAA123 in the sense take 123 and do the add operation and append it to the characters 'AAA'
i dont think the ascii add process and all will be good solution.

Campbell Ritchie
Sheriff
Posts: 50175
79
This is however an exercise in using arrays and counters. You can set up an array of 6 elements and use that array to access different letters or digits and print them like a number plate. The incrementing will then be done on a char[] array to find the next character. Agree that incrementing a String directly (probably impossible anyway) or even via a StringBuilder.

By the way: What does n /= 26; mean? That doesn't look at all right. Do you mean %=?

fred rosenberger
lowercase baba
Bartender
Posts: 12196
35
Melinda Deering wrote:It's actually a project to increment license plate numbers, so AAA123 becomes AAA124.

The question is...what happens when you increment AAA999?

or really, what happens when you increment ANY 9 in any position?

In my home state, license plates are always three letters followed by three numbers. so the next plate after AAA999 would be AAB000.

However, in some states, it's possible that any position could be a letter OR a number, so the next plate after AAA999 would be AAA99A.

How should it work in YOUR program?

Melinda Deering
Greenhorn
Posts: 11
First of all, thanks to everyone who helped me out with this. This is what I ended up submitting:

public String nextPlate ( String s ) {
int Num1 = 0, Num2 = 0, Num3 = 0, Ltr1 = 0, Ltr2 = 0, Ltr3 = 0;
carry4, carry5, carry6;

String inputString ="";
String nextPlate = "";
inputString = s;
// Process the first digit
Num1 = (int)inputString.charAt(5)- 48;
carry1 = (char)(48 + (Num1 + 1)/10);

// Process the second digit
Num2 = (int)inputString.charAt(4)- 48;
add2 = (char)(48 +(Num2+ (carry1 -48))%10);
carry2 = (char)(48 + (Num2 + (carry1 -48))/10);

// Process the third digit
Num3 = (int)inputString.charAt(3)- 48;
add3 = (char)(48 +(Num3+ (carry2 -48))%10);
carry3 = (char)(48 + (Num3 + (carry2 -48))/10);

// Process the first character
Ltr1 =(char)inputString.charAt(2)- 65;
add4 = (char)(65 + (Ltr1 + (carry3 -48))%26);
carry4 = (char)(65 + (Ltr1 + (carry3 - 48))/26);

// Process the second character
Ltr2 =(char)inputString.charAt(1)- 65;
add5 = (char)(65 + (Ltr2 + (carry4 -65))%26);
carry5 = (char)(65 + (Ltr2 + (carry4 - 48))/26);

// Process the third character
Ltr3 =(char)inputString.charAt(0)- 65;
add6 = (char)(65 + (Ltr3 + (carry5 -65))%26);
carry6 = (char)(65 + (Ltr3 + (carry5 - 65))/26);

return nextPlate;
}

Rob Spoor
Sheriff
Posts: 20661
65
You did you leave out the code tags? You've shown back in April that you know how to use them, so why not now?

Roland Shield
Greenhorn
Posts: 7
First of all, I hope people still read this topic, as it definitely pertains to an issue I am struggling with. So here is the parameters. And it is not a "license plate problem" for a class. Rather, it is a real life problem dealing with a moronic public agency that decided to us an alpha-numeric as a primary key (they are not alone, sadly) in the form of 'ADR000521723'. So, what this represents is an "ADDRESS" where there are "other" different objects with other pre-pended characters, such as "LL', which stands for "Lower Lateral", in sewer language. Talkin' dirty here. :-)

And the next three string zeroes are "padding". And the "521723" means that the Sewer District for the County of Sacramento has about that many addresses on file in a dumb database. And here is the thing: if you put the 'ADR000521723' in, say, LibreOffice Calc or MS Excel and drag it to all the rows below, guess what happens? It increases auto-magically. And no, forget the alpha. But not the padding. That to will increase as expected! Try it!

So again, it needs to leave the alpha or letters alone. Period. But the rest it needs to treat as an integer that has some funky "waiting in place" zeroes for when Sacramento has millions of addresses. But mostly it is about the "521,723" going to 521,724 and on and on. Got IT? Just like Excel or LibreOffice Calc does it.

Only I am not in a spreadsheet. I am in a software by Safe Software called FME (Feature Manipulation Engine). And they said they would create a custom *TRANSFORMER* for the world to use if I can tell them how to pull the trick that Excel and Calc have already learned.

And I have no idea. Even after reading the snippets below. I did see how it was pulled of elsewhere using SQL, but that is a non-starter in this case. It needs to happen in, preferably tcl or Python or maybe even C?

Any ideas anyone?

Dave Tolls
Ranch Hand
Posts: 1895
14
The ADR is simply a prefix for the id, plus '0' padding to make it up to the same number.
You're looking at a display problem as if it should be in the data.

You store the id (the 521723) in an auto number field and, when you display it, prefix the relevant bit.

So your full "key" is made up from two parts stored in the db.

Campbell Ritchie
Sheriff
Posts: 50175
79
• 1
And welcome to the Ranch

Roland Shield
Greenhorn
Posts: 7
Thank you for the warm welcome @Campbell Ritchie. It is appreciated for sure. And obviously, this is the place to be. Not so many "crickets" as in the ESRI forums and elsewhere. And maybe even friendlier than Slashdot or SlashGeo too.

@Dave Tolls - Thank you for your prompt and cogent reply. However, I think I may have misspoke and I apologize for that. You mention that "You're looking at a display problem as if it should be in the data." However, the subtle and somewhat sad truth is that it IS in the data. I didn't build the database and I have no control over it. I am just a technician with no voice and limited resources. And I am not alone out there. And so further still, when you say "So your full "key" is made up from two parts stored in the db.", I assume that you are speaking of how things ought to be.

However, I am struggling here with how things actually are. See the difference? I am handed a table with way too many fields. And one of those fields is [ type: String | width: 12 ] . And it is NOT a two-part tuple or object or whatever thingamagiggy you call it. No. It is one thing, an alphanumeric value. And you could say that I have be around the County once or twice and I have seen this madness more times in many places than I care to remember. But there it is.

And so one has to, I am guessing:

1) Parse the value in the "cell" or portion of the array or attribute box or whatever you call it.
2) In that parsing action, recognize letters for what they are and set them aside. inline, so to speak (a temp. variable perhaps), once the letters from the left quit "showing up".
3) Be ready for the stupid "padding" zeroes that, if nothing else provide a sentinel or flag as to the "scope" of the possible values for the integer until you have a built-in elegant meltdown and escape for when you have reached the end of the world as you know it.
4) Manage a dynamic way to keep the zeroes padding just padding until they become part of the integer value too.
5) Auto-increment the integer, which as shown in this and other forums and posts is trivial enough in any language by any monkey with a typewriter.
6) Having done step 5, re-concatenate the alpha parsed up front, the dynamically determined zero padding (either "000", "00", "0", or none as you are now approaching the end of the world), and the new, fresh integer that is one more than the previous one.
7) And here is the magic-- Make steps 1 - 6 happen recursively. Right?

And again, as the last image attachment here depicts, Bill Gates and Company cracked this egg years ago and it is built-in to Excel. And it is also built-in to LibreOffice Calc. And I believe, if I am not mistaken, that it was built-in to Lotus 1-2-3. And yet people go on in these forums as if the idea is "cray talk"?!
What gives?!

So, I need pseudo-code (or more preferably tcl, Python, or Java) that will do what has been a STANDARD SPREADSHEET FUNCTION for years and years and years. And if I can get that, I can convince the FME people to put it in their software as a Transformer and, who knows(?), thereby save the baby seals, democracy, and humanity from ourselves as we know us.

Is anyone up for the challenge?
excell2013.jpg

Campbell Ritchie
Sheriff
Posts: 50175
79
• 1
Is that an Excel document? Does it have autoincrement enabled? In which case you will be incrementing the numeric part of the key if you drag the cursor down the page. It probably uses a technique similar to what you describe in your last post to achieve that.

Have you come across this sort of thing?

Campbell Ritchie
Sheriff
Posts: 50175
79
• 1
Actually that would be
to maintain a 12‑character width.

Roland Shield
Greenhorn
Posts: 7
How would it be if it were not all about me? That is what if the value could be "justinBieber0123" ? or "G0ds\$mack000456" ? or "LL0001" ? or.... In other words, how would one dynamically anticipate and account for any sort of "alpha" up front?

And yes, it is indeed an Excel document. And Excel accepts other values besides "ADR". Seriously. Go ahead. Try it.

Campbell Ritchie
Sheriff
Posts: 50175
79
• 1
String.format(%s%09d", textPart, number);

You would probably have number++; somewhere.

Roland Shield
Greenhorn
Posts: 7
Somewhere you would have number++ ? As in the Rainbow or over the Rainbow? With Unicorns and happy clouds ? Or where?, specifically? How could I feed a table that has that attribute with 500K records and it grabs the largest one, right? And then it reads another table that has n rows of similar records with no value (yet) in that attribute, and then builds a stack or list with n items of the correct incremented alphanumerics?

So this would be a recursive function, yes? And it would happen, I am guessing, in more than one line of code? It would be more than a method with the right regular expression values filled in? How would it happen?

Mike. J. Thompson
Bartender
Posts: 689
17
• 1
I'm confused where you're actually processing this data. Are you a Java programmer writing a Java program, or do you currently just have a database full of data and no way to process it yet?

You also mentioned python as a possibility, but this is a java forum so you're likely to get Java answers here. There is a python forum on here too if you'd prefer help with python.

But it really boils down to what your requirements are, what software you have already, and what you'll do with the data after you increment it.

Actually incrementing the number in the string won't be too hard.

1) Extract the two parts of the string, the alpha part, and the numeric part without the zero padding. Either use a regular expression or write something yourself to do this.

2) convert the numeric part to a number (either an int or a long, depending on the maximum size the number can be).

3) increment the number.

4) append the new number to the old string. remember to append the right number of zeroes. also, what happens if the value overflows?

Roland Shield
Greenhorn
Posts: 7
Thank you, Mr. Thompson. I am done. First, I posted it in here because, after doing a "reasonable" search on the topic, I found very little out there. Yes, it is discussed in detail in threads in the context of SQL. But after that, it gets rather thin rather quickly...at least as far as I could tell.
If there is a Python forum that discusses this topic, I will certainly go there.

But again, I am only here because: A) there seem to be people knowing how to wrestle with the problem B) I need answers.

I am not a JAVA programmer. And will never be one. I do know one though. <grin>

I am using three softwares: ESRI ArcSDE/ArcGIS, MAXIMO, and FME. The first one is "friendly" with Python, the second is not friendly, and the third is "friendly" with tcl and Python.

All done.

Winston Gutkowski
Bartender
Posts: 10527
64
• 1
Roland Shield wrote:But again, I am only here because: A) there seem to be people knowing how to wrestle with the problem B) I need answers.
...
I am using three softwares: ESRI ArcSDE/ArcGIS, MAXIMO, and FME. The first one is "friendly" with Python, the second is not friendly, and the third is "friendly" with tcl and Python.

To be honest, I don't think this problem has anything to do with software at all; it has to do with understanding the exact nature of your key.

From what you've shown us so far (and please correct me if I'm wrong), this would appear to be a 6-digit numeric key, with the prefix "ADR000" added in for display purposes because that's what people are used to seeing. You refer to other components (such as 'lower lateral'), but you don't explain what they are, or how they affect your key.

The 6-digit numeric part is easy, and has already been explained. In SQL you could even make it an automatic sequence that ends (or rolls over) at 999999; but if those last 6 digits are dependant on OTHER parts of the key, then you need to explain to us exactly how they work - for your own information (I suspect) as much as ours.

Understanding solves problems; not software.

HIH

Winston

Roland Shield
Greenhorn
Posts: 7
Okay, sorry. So I only mentioned the "LL" as an example of a primary key for another "type" of "asset". But in order to simplify the issue and make it more "abstract", let me use a generic, made-up model.
Let's say there is a fruit basket. And that "fruit basket" is a table of records. And in that table of records, there are tuples (records, listings, instantiated objects(?) ) of fruit. There are Orange Records and there are Apple Records and there are Banana Records. And each have attributes. And since they are all in the same table, they have the same set of attributes, populated or not. And one of those attributes is the "fruitKey". So, fruitKey might have a value of 'Orange0001', 'Banana00027', or Apple00013'. And my task it to take the largest record (the last record entered into the fruitBasket) and add one to it for the next record. But not only the next record, but, in fact, the next n records, where I have determined n elsewhere. Thus, n would b a parameter of this function. And, by the way, I am doing this so that I can put the next n records (or pieces of fruit) into the basket, my fruitBasket table need record inserts; n of them, in fact.

And a curious thing is that when I add to the fruit basket, I only add one kind of fruit at a time. So if I put, for example, 30 apples in the basket, well, I am only putting apples on this go. But, I don't know, up front, what sort of fruit was put in last. Further, management may have started putting a new fruit too! So I can't simply have a handy list of Apples, Bananas, and Oranges. No siree! No, I need to be ready for the wiseguys upstairs to throw dates, kiwis, kumquats, even tomatoes or who knows what else!? So I have to get the "largest" and "last" value from the fruitBasket and the very first thing I need to do after that is parse the alpha (everything that is a letter + 3 zeroes treated as letters too) and "stage" it, perhaps, in a temp variable in the function perhaps that goes away after all this funny business is done? Yes?

And to reiterate the above, I need to be ready to fetch ANY sort of alpha combo which, after being fetched, with remain "static" and with the 3 zeroes be concatenated back to the integer index ++, okay?

And I need this all to happen n times.

Now, if you look at my original post with the attached screenshots, it includes one of Excel. Why? Because Excel does the above for any stinking combination of aaa00012345 you throw at it. It doesn't need a list of the alpha. It recognizes them for what they are up front, on the fly, so to speak. And I suppose that the click-and-drag part is kind of mimicking, in a way, the n number of records part. But the n is only as far, in that case, as you drag your hand, yes?

So, does that clarify a more full understanding of the problem? And when I say "problem", that seems like a strong word to me. Why? Well, for one, get this-- the magic function in MS Excel does the following, which is cool- say your last record was 'Banana00098' and you want add three more pieces of fruit and they also happened to be, in this case 3 more bananas. And so what does it do? Well, on-the-fly, it adds the following 'Banana00099', 'Banana00100', 'Banana00101' !

Did you just see that ?! Is that amazing or what ?! MS Excel saw what was sitting there as a series of three zeroes that were just padding and transmogrified them to accommodate the larger integer index++ by dumping one of the padding zeroes and now having only 2. Is that cool? And no problem, right?

Don't believe me? Go try it yourself in Microsoft Excel or LibreOffice Calc. Seriously. I double dare you!

Winston Gutkowski
Bartender
Posts: 10527
64
• 1
Roland Shield wrote:So, does that clarify a more full understanding of the problem?

Yup.

And when I say "problem", that seems like a strong word to me. Why? Well, for one, get this-- the magic function in MS Excel does the following, which is cool- say your last record was 'Banana00098' and you want add three more pieces of fruit and they also happened to be, in this case 3 more bananas. And so what does it do? Well, on-the-fly, it adds the following 'Banana00099', 'Banana00100', 'Banana00101' !

Ah, but does it? That function only works when you use the "insert rows" utility; and I'm pretty sure that it will only increment the LAST key that was entered, so if you wanted to add a bunch of Oranges, you're out of luck. It also doesn't necessarily protect your "000" prefix, and will happily plough overflow digits into it unless you define your format correctly.

And this is what I'm talking about: YOU must define the rules for "incrementing". And the only way to do that is to understand, in precise detail, what is required in every case.

HIH

Winston

Roland Shield
Greenhorn
Posts: 7
Gotcha. Well, here is the deal in my case: It is addresses. And ostensibly, they want to be ready for a gnarly world in the future with hundreds of millions of them in Sacramento. And so the zeroes need to get chewed up and turned into legitimate integers, as the numbers grow from the hundreds of thousands, and then into the millions, and then into the tens of millions, and finally into the hundreds of millions. And the assumption is that by the time we get to one billion addresses in Sacramento, that we will all be dead and it won't matter anymore.

However, you bring up a great point. That is, the "tool" that would be created would need "hooks" for a dynamic selector with input from the user that had the zero padding parameter and behavior. I am going to bug the FME guy and ask him if this is enough to go on for the transformer.