Tony
Tony

Reputation: 3638

Java Stringbuilder.replace

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

Answers (5)

anubhava
anubhava

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

user1190541
user1190541

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

DwB
DwB

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

Ernest Friedman-Hill
Ernest Friedman-Hill

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

Dervall
Dervall

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

Related Questions