Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

logically sorting a mixed string of uppercase letters and numbers

I've got a string of uppercase letters and numbers that I must 'logically' sort and store in a field in a database. I've got the update/change/inquire part into the database figured out. I'm struggle with logically sorting this string.

Here goes, I hope I can explain this well.

Given this set of strings AB1 AB2 AB3 A11 AB10

I need these to alpha sort like so

A11 AB1 AB2 AB3 AB10

in order to achieve this, I believe I need to explode the string. because currently trying to alpha sort yields A11 AB1 AB10 AB2 AB3

EDIT: I need to be able to store an exploded string and a non exploded string to be able to sort with other programs.

Here is how I think they need to be broken up and stored in order to sort alpha

A11  -  A   11
AB1  -  AB   1
AB2  -  AB   2
AB3  -  AB   3
AB10 -  AB  10

There are some constants. The string will be no larger than 5 positions. It will only contain upper case letters and numbers.

Here is as far as I've gotten with my code. writers block so i'm hoping for some help. I think I need to find if it starts with a letter, then find all the consecutive letters, move those left alight, then go to work on number, finding all the consecutive numbers and move those right aligned. Not sure how something like 'A1B1' would work either...

for(int ii = 0;ii < sectionString.length() && ii< SECTIONSPACES;ii++){
               System.out.print("    Was previous a number? " + isPreviousANumber +         "\n");
try{
    String tmpString = sectionString.substring(ii,ii + 1 );
    int positionInCharArray = Integer.parseInt(tmpString);
    System.out.printf("    Position " + ii + " is number " + positionInCharArray + "\n");
    isPreviousANumber = true;        
}catch(Exception e){
    System.out.printf("    Position " + ii + " number is not a number " +      sectionString.substring(ii,ii) + "\n");
    isPreviousANumber = false;
    }                   
}
like image 823
nkuebelbeck Avatar asked Oct 20 '22 23:10

nkuebelbeck


1 Answers

This remark "Not sure how something like 'A1B1' would work either..." somewhat increases the complexity of the problem. The following should work for all cases.

Method:

Divide the string into tokens. A token is either a letter or a consecutive run of digits. Pad each digits-token to five characters with leading spaces. Concatenate the tokens to make the exploded string.

From a 5 character original, the longest exploded string will be 17 characters.

The resulting exploded strings may be sorted by any program, or by a SQL "ORDERED BY" clause.

Examples:

1A1A1   "    1A    1A    1"
11A11   "   11A   11"
1111A   " 1111A"
11111   "11111"
A1      "A    1"
A1B1    "A    1B    1"
A1C     "A    1C"
A2      "A    2"
A2B1    "A    2B    1"
A10     "A   10"
A10B1   "A   10B    1"
A11     "A   11"
AA1     "AA    1"
AB1     "AB    1"
AB2     "AB    2"
AB10    "AB   10"
ABC     "ABC"

Pseudocode:

// original = "section" string
exploded = ""
prevdigits = false
for ii from 1 to length(original) {
   ch = original[ii]
   if (ch is a digit) then {
      if not prevdigits then {
         token = ""
         prevdigits = true
      }
      token = token+ch
   } else { // letter
      if prevdigits then {
         exploded = exploded + spaces(5-length(token)) + token
         prevdigits = false
      }
      exploded = exploded + ch
   }
}

-Al.

like image 54
A. I. Breveleri Avatar answered Nov 02 '22 10:11

A. I. Breveleri