yydl
yydl

Reputation: 24474

Reverse characters in Java while keeping some in place

I have a String and want to reverse it so that some characters get reversed, while others remain in place. How can I implement that (e.g. lets say I want all letters to reverse while all numbers stay in place)?

Upvotes: 2

Views: 2989

Answers (2)

Matt
Matt

Reputation: 754

It sounds like you want something like myReverse("a1b2c3d") to be "d1c2b3a".

Use two indices, one going from each end of the string, looking for swappable characters.

Here's some pseudocode:

i1 = 0; i2 = len - 1;
while (i1 < i2) {
  while (isCharacterThatShouldNotBeSwapped(str.charAt(i1)) && i1 < i2)
    i1++;
  while (isCharacterThatShouldNotBeSwapped(str.charAt(i2)) && i1 < i2)
    i2--;
  if (i1 < i2)
    swapChars(str, i1, i2); /* swap characters at positions i1 and i2 in str */
  i1++; i2--;
}

Upvotes: 4

amit
amit

Reputation: 178521

You can create an automaton for it:
iterate over the string, insert each letter into the stack and replace it with a special character which is not in the original string (i.e. $), do not change digits at all.
iterate over the string again, replace every $ with the head of the stack.
note: since String is immutable you will need to first export it to a StringBuilder or CharSequence
EDIT
for example:

    String inp = "a45string1test";
    char[] cs = new char[inp.length()];
    inp.getChars(0, inp.length(), cs, 0);
    Stack<Character> stack = new Stack<Character>();
    for (int i =0;i<cs.length;i++) {
        if (Character.isDigit(cs[i])) continue;
        stack.push(cs[i]);
        cs[i] = '$';
    }
    for (int i=0;i<cs.length;i++) {
        if (cs[i] == '$') cs[i] = stack.pop();
    }
    System.out.println(cs);

result will be t45setgni1rtsa
complexity is O(n): iterating the string (twice) - since all stack operations are O(1).

Upvotes: 4

Related Questions