2
\$\begingroup\$

I'm trying to reduce consecutive elements of array to one, but not for all values like:

{3,0,0,0,3,3,3,0,0,0} => {3,0,3,0}

but for specific one, in my example 0:

{3,0,0,0,3,3,3,0,0,0} => {3,0,3,3,3,0}

so only zeros (the threes are intact) are reduced.

I have Java String working code I wrote:

public static String removeConsecutive(String str, char remove) {
 char[] chars = str.toCharArray();
 int current = 0;
 int result = current;
 while (current < chars.length) {
 if (chars[current] == remove) {
 // keep the first occurrence
 chars[result++] = chars[current++];
 // ignore the others
 while (current < chars.length && chars[current] == remove) {
 ++current;
 }
 } else { 
 chars[result++] = chars[current++];
 }
 }
 return new String(chars, 0, result);
}

and it does the trick:

public static void main(String[] args) {
 System.out.println(removeConsecutive("000300300030303330000", '0'));
}

outputs: 0303030303330

Can anyone suggest any improvements, since it think the code is not perfect. It's doesn't have to be String in use, but with any other array.

asked Jun 13, 2013 at 9:16
\$\endgroup\$

6 Answers 6

1
\$\begingroup\$

Here's the same answer that I gave on you Stack Overflow:

Think this is clearer, and does the job:

public static String removeConsecutive(String str, char remove) {
 StringBuilder sb = new StringBuilder();
 for(char c : str.toCharArray()) {
 int length = sb.length();
 if(c != remove || length == 0 || sb.charAt(length - 1) != c) {
 sb.append(c);
 }
 }
 return sb.toString();
}
answered Jun 13, 2013 at 11:27
\$\endgroup\$
5
\$\begingroup\$

You can have the same output with regex , using Arrays.toString(char[]):

System.out.println("000300300030303330000".replaceAll("[0]+", "0"));

or, with a parameter :

char charToRemove = '0' ;
System.out.println("000300300030303330000".replaceAll("[" + charToRemove + "]{1,}", charToRemove + ""));

or change charToRemove + "" in Character.toString(charToRemove) more academic.

answered Jun 13, 2013 at 9:27
\$\endgroup\$
6
  • \$\begingroup\$ {1,} is just + ;) \$\endgroup\$ Commented Jun 13, 2013 at 9:35
  • \$\begingroup\$ @fge changed, both works \$\endgroup\$ Commented Jun 13, 2013 at 9:38
  • \$\begingroup\$ Hi @cl-r, tnx for your answer, but I'm trying to avoid regex and replace / replaceAll methods when removing only one char, since it inefficient. \$\endgroup\$ Commented Jun 13, 2013 at 10:20
  • 1
    \$\begingroup\$ @robosoul It is more efficient to declare static field Pattern.compile(regex); and use them as needed ; powerful with complex matches. It would be intresting to compare regex and StringBuilder response time with many arrays to test. \$\endgroup\$ Commented Jun 13, 2013 at 10:33
  • \$\begingroup\$ Nit: When matching a single character 0+ does the same job as [0]+. \$\endgroup\$ Commented Jun 13, 2013 at 12:23
3
\$\begingroup\$

Another apporach to the removeConsecutive method, using a StringBuilder and String.charAt():

public static String removeConsecutive(String str, char remove) {
 final StringBuilder sb = new StringBuilder(str.length());
 int i = 0;
 while(i < str.length()) {
 if(i == 0 || str.charAt(i) != remove || str.charAt(i) != str.charAt(i-1)) 
 sb.append(str.charAt(i));
 i++;
 }
 return sb.toString();
}
answered Jun 13, 2013 at 9:38
\$\endgroup\$
1
\$\begingroup\$

This is another solution:

public static String removeConsecutive(String str, char remove)
{
 final StringBuilder sb = new StringBuilder(str.length());
 boolean seen = false;
 for (final char c: str.toCharArray()) {
 if (c == remove) {
 if (!seen) {
 sb.append(c);
 seen = true;
 }
 continue;
 }
 seen = false;
 sb.append(c);
 }
 return sb.toString();
}
answered Jun 13, 2013 at 9:42
\$\endgroup\$
1
\$\begingroup\$

This may be not the most efficient solution but works fine

public static String removeConsecutive(String str, char remove) {
 String result = str;
 String removeAsString = String.valueOf(remove);
 String searchText = removeAsString + removeAsString;
 while(result.indexOf(searchText) > -1) {
 result = result.replace(searchtext, removeAsString);
 }
 return result;
}
answered Jun 13, 2013 at 11:54
\$\endgroup\$
1
\$\begingroup\$

This one came from my friend, sticking to the original char array idea:

private static String removeConsecutive(final String str, final char remove) {
 final char[] chars = str.toCharArray();
 char current;
 char previous = 0;
 int i = 0, result = 0;
 while (i < chars.length) {
 current = chars[i];
 if (current != previous || current != remove) {
 chars[result++] = current;
 }
 previous = current;
 ++i;
 }
 return new String(chars, 0, result);
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
answered Jun 14, 2013 at 1:26
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.