HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMajor

Reversing a String using Stack

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
stringreversingusingstack

Problem

Is this code okay?

import java.util.Stack;

public class StackReverse {

    public static void main(String[] args) {

        final String inputString = "code review";

        final String reversed = reverseString(inputString);
        System.out.println("The reversed string is " + reversed);

    }

    public static String reverseString(String originalString) {
        Stack stack = new Stack<>();
        String reversed = "";
        for (int i = 0; i < originalString.length(); i++) {
            char ch = originalString.charAt(i);
            stack.push(ch);
        }
        for (int i = 0; i < originalString.length(); i++) {
            char ch = stack.pop();
            reversed = reversed + ch;

        }
        return reversed;

    }

}

Solution

Unicode is hard to get right, especially in Java as it has a more or less broken concept of a “character”. An Unicode code point is a 21-bit number. These code points are encoded to bytes with the UTF-8 or UTF-16 encodings (well, there are a couple more…). But when Java was created, Unicode only had characters in a 16-bit range, and code points were encoded with the (now deprecated) UCS-2 encoding.

There's a lot of pain from the fact that the 21-bit Unicode code points don't fit into a single 16-bit char or Character in Java. Two consecutive chars might actually be surrogate pairs. When reversing a string, we have to special-case these. We can use the Character.isHighSurrogate(char) function to test whether a given char starts a surrogate pair. If we encounter such a code point, we advance to the next char in the string, and push it onto the stack first:

for (int i = 0; i < originalString.length(); i++) {
    char ch = originalString.charAt(i);
    if (Character.isHighSurrogate(ch)) {
        i++;
        if (i < originalString.length()) {
            stack.push(originalString.charAt(i));
        }
    }
    stack.push(ch);
}


As a test case, you can reverse a string with the smiley character : "hi \ud83d\ude03". Reversed, it should be "\ud83d\ude03 ih".

It is best to think of Java's char as “an UTF-16 code unit” (see Wikipedia for all the details about UTF-16 you didn't want to know, but should). To learn about what Unicode is, and how to tame it, start with Joel Spolsky's Unicode blog post.

Code Snippets

for (int i = 0; i < originalString.length(); i++) {
    char ch = originalString.charAt(i);
    if (Character.isHighSurrogate(ch)) {
        i++;
        if (i < originalString.length()) {
            stack.push(originalString.charAt(i));
        }
    }
    stack.push(ch);
}

Context

StackExchange Code Review Q#64147, answer score: 21

Revisions (0)

No revisions yet.