Reputation: 24474
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
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
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