0
\$\begingroup\$

Given a string, that contains special character together with alphabets (‘a’ to ‘z’ and ‘A’ to ‘Z’), reverse the string in a way that special characters are not affected.

Example: Input: str = "a:b!c" Output: str = "c:b!a"

I am using two indexes one to start from the beginning and the other from the end of the array.Swap if they are valid chars and then increment indexes,increment indexes if invalid chars.Any feedback appreciated!

P.S: I am using static methods for convenience.

The Code:

public class ReverseArrayWithoutSpecialChars {

    static HashSet<Character> invalidChars = new HashSet<Character>(Arrays.asList(',', '?', ':','!','$'));

    public static char[] reverseSkippingSpecialChars(char[] charArray) {

        int l = 0;
        int r = charArray.length - 1;
        for (int i = 0; i < charArray.length; i++) {

            if (r <= l) {
                break;
            }
            if (!isInvalidChar(charArray[l]) && !isInvalidChar(charArray[r])) {
                charArray = swapChars(charArray, l, r);
                l++;
                r--;
            } else if (isInvalidChar(charArray[l])) {
                l++;
            } else if (isInvalidChar(charArray[r])) {
                r--;
            }
        }
        return charArray;
    }

    public static char[] swapChars(char[] charArray, int index1, int index2) {
        char temp = charArray[index1];
        charArray[index1] = charArray[index2];
        charArray[index2] = temp;
        return charArray;
    }

    public static boolean isInvalidChar(char character) {
        return invalidChars.contains(character);
    }

    public static void main(String args[]) {
        char[] charArray = new char[]{'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};

        System.out.println(reverseSkippingSpecialChars(charArray));
    }
}
\$\endgroup\$
1
\$\begingroup\$

Class fields

    static HashSet<Character> invalidChars = new HashSet<Character>(Arrays.asList(',', '?', ':','!','$'));

You might as well go ahead and make this final as well.

    public static final Set<Character> invalidChars = new HashSet<>(Arrays.asList(',', '?', ':', '!', '$'));

As a final variable, it's clear that it won't change.

We should probably specify a visibility. Unless it's a secret, we should go ahead and make it public. Since it's final, no one can change it.

It is better to type to the interface than the implementation. This allows us to change the implementation without changing the type. And it forces us to limit ourselves to the operations available in the interface.

In newer versions of Java, you don't need to say Character twice. The compiler will figure out the type on the second one.

Eliminate unnecessary variables

        int l = 0;
        int r = charArray.length - 1;
        for (int i = 0; i < charArray.length; i++) {

            if (r <= l) {
                break;
            }

You can write this either

        for (int l = 0, r = charArray.length - 1; l < r; ) {

or

        int l = 0;
        int r = charArray.length - 1;
        while (l < r) {

You don't need the extra i variable. Nor do you need to do the l < r check separately.

It's up to you if you use a for or a while. Either will work. The for is a bit more compact, but you have to leave the update section blank. Either will be shorter.

Not really invalid

            if (!isInvalidChar(charArray[l]) && !isInvalidChar(charArray[r])) {
                charArray = swapChars(charArray, l, r);
                l++;
                r--;
            } else if (isInvalidChar(charArray[l])) {
                l++;
            } else if (isInvalidChar(charArray[r])) {
                r--;
            }

It's not that the characters are invalid. They are expected and you want to preserve them. It's that the character are special and treated different. Consider

            if (isSpecialChar(charArray[l])) {
                l++;
            } else if (isSpecialChar(charArray[r])) {
                r--;
            } else {
                // neither is a special character
                swapChars(charArray, l, r);
                l++;
                r--;
            }

You use the terminology special elsewhere, so why not here?

I also like that this emphasizes the positive.

Since we already know that neither character is a special character, we don't have to check again.

The swapChars method modifies the charArray in place. We don't have to return it and assign.

Generating a character array

        char[] charArray = new char[]{'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};

If you want to type less, consider

        char[] charArray = {'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};

or

        char[] charArray = "abcd?fs:w".toCharArray();

No big deal, but why type more than necessary?

\$\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.