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.

\$\endgroup\$
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();
}
\$\endgroup\$
4
\$\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.

\$\endgroup\$
6
  • \$\begingroup\$ {1,} is just + ;) \$\endgroup\$
    – fge
    Jun 13 '13 at 9:35
  • \$\begingroup\$ @fge changed, both works \$\endgroup\$
    – cl-r
    Jun 13 '13 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\$
    – robosoul
    Jun 13 '13 at 10:20
  • \$\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\$
    – cl-r
    Jun 13 '13 at 10:33
  • \$\begingroup\$ Nit: When matching a single character 0+ does the same job as [0]+. \$\endgroup\$
    – l0b0
    Jun 13 '13 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();
}
\$\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();
}
\$\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;
}
\$\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);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.