PuppyKevin
PuppyKevin

Reputation: 3057

Calculating next value from a String

Within my code, I'm trying to get it to calculate the next value of a random string, where the string follows this format:

AAA-AAAA-AAA-AAA

The next value would be AAA-AAAA-AAA-AAB, getting to AAA-AAAA-AAA-AAF, which will in turn get to AAA-AAAA-AAA-AA1, and so on until it gets to 9.

From there, it should go ahead and increment the letter ahead of it, making it AAA-AAAA-AAA-ABA, and starting the process all over.

How exactly would I accomplish this in Java? I'm thinking recursion, but I have no clue where to start.

Upvotes: 0

Views: 742

Answers (4)

kapunga
kapunga

Reputation: 436

If you are just trying to increment by one, you should be able to do it by defining a String with your digits in order, then looping through your random string from back to front, skipping all that aren't in your defined digits and incrementing. This should work for any arbitrary definition of a set of digits.

public String incrementString(String randomString) {
    // The ordering of digits.
    String digits = "ABCDEF123456789";

    // A StringBuffer to do a transform
    StringBuffer inPlace = new StringBuffer(randomString);

    // Loop through all of the digits of your random string...
    for (int i = 0 ; i < inPlace.length() ; i++) {
        // The index we are checking since we are traversing
        // back to front.
        int stringIndex = inPlace.length() - (i + 1);

        // This is the index of the digit at 'stringIndex' 
        // in our 'digits' String
        int digitIndex = digits.indexOf(stringIndex);

        // If it's not there (meaning we have found a '-' character)
        // just continue.
        if (digitIndex == -1) {
            continue; 
        // If it is not the last character in our 'digits' String, we can 
        // just replace and return.
        } else if (digitIndex < digits.length() - 1) {
            inPlace.setCharAt(stringIndex, digits.charAt(digitIndex + 1));
            return inPlace.toString();

        // If it IS the last character in our 'digits' String, we need to
        // replace it with the first character in our 'digits' String and
        // keep going.
        } else {
            inPlace.setCharAt(stringIndex, digits.charAt(0));
        }
    }

    // In the event that every character in our random string was the
    // last digit in our 'digits' String, (In this case, 999-9999-999-999) 
    // we will exit the loop without returning, so do it here.
    return inPlace.toString();
}

Upvotes: 0

dtech
dtech

Reputation: 14060

The simplest is to convert your string to integers and back. From your post I'm guessing that the order of your digits is ABCDEF123456789 (0 to 14) so I'll use that. The order 0123456789ABCDEF is much more common, in that case you can use hexadecimal which are provided by library functions.

private static final char[] digitMap = new char[] {'A','B','C','D','E','1','2','3','4','5','6','7','8','9'};
private static final int base = digitMap.length;     
private static final Map<Character, Integer> reverseDigitMap = new HashMap<>();
static {
     // populate the reverse digit map
     for(int i=0;i<base;i++) {
          reverseDigitMap.put(digitMap[i], i);
     }
}

public static String toMyFormatString(long number) {
    StringBuilder res = new StringBuilder();
    // Add 13 digits to string in reverse order
    for(int i=0;i < 13;i++) {
         // Add dashes at correct locations
         if(i==3 || i == 6 || i == 10) { res.append('-') };
         // Output a character
         res.append(digitMap[number % base]);
         number = number / base;
    }
    // Change the order
    res.reverse();
    return res.toString();
}

/**
* @throws NullPointerException when an incorrect digit is encountered
**/
public static long fromMyFormatString(String numberString) {
    long result = 0;
    // Number is 16 characters of which 13 are digits
    for(int i = 0; i < 16; i++) {
          char digit = numberString.charAt(i);
          // Skip "-"
          if(digit == '-') { continue; };
          result = result * base; // We're adding the next digit
          result = result + reverseDigitMap.get(digit);
    }
    return result;
}

Upvotes: 2

Scott Shipp
Scott Shipp

Reputation: 2301

My idea is that an enumerated type would make this easier. Add a nextValue method like this. Use it in your addition logic. Just by calling .nextValue() you'll get what the next "digit" should be, if .nextValue ever turns out to be "A" then you can implement logic for carrying the value. A simple way to represent each overall "number" might be a list. But this below shoulde ease things a bit because the flip-over from 9 to A is built-in.

enum myEnum { 
       //had to use A1-A9 to represent the numbers because numbers themselves are not allowed
    A, B, C, D, E, F, A1, A2, A3, A4, A5, A6, A7, A8, A9;

    public myEnum nextValue() {
        return this.ordinal() < myEnum.values().length - 1
                ? myEnum.values()[this.ordinal() + 1]
                : A; //returns A if the value of this.ordinal = A9
    }

};

You can add different methods to your enum like .toString(), .valueOf() etc. to return the values of each digit in any format you like.

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533500

If you have a fixed format you need to follow you can use either a counter in based 15 (values A-F1-9) or you can increment a formatted value. All you need is a simple loop starting at the end. If you have a value less than Z increment and stop, If you have Z, return to A and step back one. (carry)

BTW, This sounds like a modified hexidecimal format. Is this what you intended.

Upvotes: 0

Related Questions