Reputation: 3638
Consider the following inputs:
String[] input = {"a9", "aa9", "a9a9", "99a99a"};
What would be the most efficient way whilst using a StringBuilder to replace any digit directly prior to a nine with the next letter after it in the alphabet?
After processing these inputs the output should be:
String[] output = {"b9", "ab9", "b9b9", "99b99a"}
I've been scratching my head for a while and the StringBuilder.setCharAt was the best method I could think of.
Any advice or suggestions would be appreciated.
Upvotes: 5
Views: 1153
Reputation: 785196
You can following code:
String[] input = {"a9", "aa9", "a9a9", "99a99a", "z9", "aZ9"};
String[] output = new String[input.length];
Pattern pt = Pattern.compile("([a-z])(?=9)", Pattern.CASE_INSENSITIVE);
for (int i=0; i<input.length; i++) {
Matcher mt = pt.matcher(input[i]);
StringBuffer sb = new StringBuffer();
while (mt.find()) {
char ch = mt.group(1).charAt(0);
if (ch == 'z') ch = 'a';
else if (ch == 'Z') ch = 'A';
else ch++;
mt.appendReplacement(sb, String.valueOf(ch));
}
mt.appendTail(sb);
output[i] = sb.toString();
}
System.out.println(Arrays.toString(output));
OUTPUT:
[b9, ab9, b9b9, 99b99a, a9, aA9]
Upvotes: 1
Reputation:
another solution is for example to use
StringUtils.indexOf(String str, char searchChar, int startPos)
in a way as Ernest Friedman-Hill pointed, take this as experimental example, not the most performant
Upvotes: 0
Reputation: 38300
Use a 1 token look ahead parser technique. Here is some psuedoish code:
for (int index = 0; index < buffer.length(); ++index)
{
if (index < buffer.length() - 1)
{
if (buffer.charAt(index + 1) == '9')
{
char current = buffer.charAt(index) + 1; // this is probably not the best technique for this.
buffer.setCharAt(index, current);
}
}
}
Upvotes: 0
Reputation: 81694
Since you have to look at every character, you'll never perform better than linear in the size of the buffer. So you can just do something like
for (int i=1; buffer.length() ++i) // Note this starts at "1"
if (buffer.charAt[i] == '9')
buffer.setCharAt(i-1, buffer.getCharAt(i-1) + 1);
Upvotes: 2
Reputation: 5744
You want to use a very simple state machine. For each character you're looping through in the input string, keep track of a boolean. If the character is a 9, set the boolean to true. If the character is a letter add one to the letter and set the boolean to false. Then add the character to the output stringbuilder.
For input you use a Reader
. For output use a StringBuilder
.
Upvotes: 0